Skip to content

Instantly share code, notes, and snippets.

@mono0926
Last active September 10, 2024 01:38
Show Gist options
  • Save mono0926/8042ebe8b649f39b9e36b87bf0e1d594 to your computer and use it in GitHub Desktop.
Save mono0926/8042ebe8b649f39b9e36b87bf0e1d594 to your computer and use it in GitHub Desktop.
Sliver
import 'dart:collection';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:intl/intl.dart';
void main() => runApp(const App());
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
// DartPadなどのWebなどでスクロール操作ができるように(サンプル用の措置)
scrollBehavior: const MaterialScrollBehavior().copyWith(
dragDevices: PointerDeviceKind.values.toSet(),
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('CupertinoSliverRefreshControl')),
body: const Row(
children: [
Expanded(
child: ListBox(
titleLabel: 'OK🙆‍♀️(表示領域前後のみ描画)',
child: OkListView(),
),
),
Expanded(
child: ListBox(
titleLabel: 'NG🙅‍♂️(よく見る一気に描画パターン)',
child: NgListView(),
),
),
],
),
);
}
}
class ListBox extends StatelessWidget {
const ListBox({super.key, required this.child, required this.titleLabel});
final String titleLabel;
final Widget child;
@override
Widget build(BuildContext context) {
return Column(
children: [
ListTile(
title: Text(titleLabel),
),
Expanded(child: child),
],
);
}
}
final _colors = UnmodifiableListView([
Colors.red,
Colors.green,
Colors.blue,
Colors.yellow,
Colors.purple,
Colors.orange,
Colors.pink,
Colors.teal,
Colors.cyan,
Colors.indigo,
]);
class OkListView extends HookWidget {
const OkListView({super.key});
@override
Widget build(BuildContext context) {
final colors = useState(_colors.toList());
return CustomScrollView(
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
slivers: [
CupertinoSliverRefreshControl(
onRefresh: () async {
await Future<void>.delayed(const Duration(seconds: 1));
colors.value = List.of(_colors)..shuffle();
},
),
SliverList.list(
children: [
for (var i = 0; i < 100; i++)
Item(
color: colors.value[i % colors.value.length],
),
],
),
],
);
}
}
class NgListView extends HookWidget {
const NgListView({super.key});
@override
Widget build(BuildContext context) {
final colors = useState(_colors.toList());
return CustomScrollView(
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics(),
),
slivers: [
CupertinoSliverRefreshControl(
onRefresh: () async {
await Future<void>.delayed(const Duration(seconds: 1));
colors.value = List.of(_colors)..shuffle();
},
),
SliverToBoxAdapter(
child: Column(
children: [
for (var i = 0; i < 100; i++)
Item(
color: colors.value[i % colors.value.length],
),
],
),
),
],
);
}
}
class Item extends HookWidget {
const Item({super.key, required this.color});
final Color color;
static final _timeFormat = DateFormat.Hms();
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final createdTime = useMemoized(DateTime.now);
void log(String message) => print('${DateTime.now()}: $message');
useEffect(
() {
log('init');
return () => log('disposed');
},
[],
);
return Container(
alignment: Alignment.center,
height: 100,
color: color,
child: Text(
_timeFormat.format(createdTime),
style: theme.textTheme.headlineSmall!.copyWith(
color: ThemeData.estimateBrightnessForColor(color) == Brightness.light
? Colors.black
: Colors.white,
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment