😎

Flutterで無限スクロールとiOSのステータスバーをタップしてスクロールを両立させる

2023/05/03に公開

はじめに

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点を守るだけで、うまく行きました。

参考記事

Flutter 点击状态栏回到顶部,滚动监听 - 简书

Discussion