😎
Flutterで無限スクロールとiOSのステータスバーをタップしてスクロールを両立させる
はじめに
FlutterでSNSでタイムライン機能を実装しようとした時に引っかかりました。
FlutterのListView
で無限スクロール機能を実装すると、iOSのステータスバーをタップしても最上部にスクロールしません。
そこでFlutterで無限スクロール機能とiOSのステータスバーをタップして上にスクロールする動作を両立させる方法を示します。
最初はFlutterで無限スクロールをScrollContollerを使って実装する際のTips - Qiitaの記事を参考に実装しましたが、手元ではうまく行きませんでした。
改善前のコード
main.dart
class BlueskyTimelineState extends State<BlueskyTimeline> {
final ScrollController _scrollController = ScrollController();
void initState() {
super.initState();
_fetchTimeline();
_scrollController.addListener(_scrollListener);
}
// 無限スクロールを実装
void _scrollListener() {
ScrollController controller = PrimaryScrollController.of(context);
if (controller.position.pixels == controller.position.maxScrollExtent) {
_loadMoreTimelineData();
}
}
main.dart
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
itemBuilder: (context, index) {
return _buildListItem(_items[index]);
},
itemCount: _items.length,
);
}
改善後のコード
main.dart
class BlueskyTimelineState extends State<BlueskyTimeline> {
- final ScrollController _scrollController = ScrollController();
void initState() {
super.initState();
_fetchTimeline();
- _scrollController.addListener(_scrollListener);
}
+
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ PrimaryScrollController.of(context).addListener(_scrollListener);
+ }
// 無限スクロールを実装
void _scrollListener() {
ScrollController controller = PrimaryScrollController.of(context);
if (controller.position.pixels == controller.position.maxScrollExtent) {
_loadMoreTimelineData();
}
}
main.dart
@override
Widget build(BuildContext context) {
return ListView.builder(
- controller: _scrollController,
itemBuilder: (context, index) {
return _buildListItem(_items[index]);
},
itemCount: _items.length,
);
}
ポイント
-
didChangeDependencies()
をオーバーライドすることで、PrimaryScrollControllerに対しaddListenerで無限スクロールの機能を実装する。 -
ListView.builder()
でcontroller
は絶対に設定しない
上記2点を守るだけで、うまく行きました。
Discussion