📑

'package:flutter/src/widgets/scroll_controller.dart': Failed assertion

2024/12/14に公開

Flutterのスクロールに関するエラー

tabbarを押下したら、tabbarViewに表示されているListViewbuilderの表示を初期(一番上)に戻すという実装をした際に下記に遭遇。

'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 201 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.

エラー内容

_positions.isNotEmpty というアサーション(条件)が満たされていないため、プログラムが中断している。
ScrollController がまだどのスクロールビューにも「アタッチされていない(結びついていない)」状態でメソッドが呼び出されようとしている状態。

簡単にいうと、スクロールを監視しているScrollControllerがListViewBuilderなどのプロパティにありますが、そちらが画面描画されてアタッチ(付与)される前に使われているらしく、エラーが起きていました。

画面的には動作するのですが、ログにエラー表示される状態です。

scrollController.hasClients を利用

下記の様に修正して、エラー回避。
tabボタンを押下した際に、どのタブのスクロールを一番最初に戻すのかをonTap内で処理しています。

scrollControllerがあるなら、tabControllerもありまして、tabControllerを利用してどのタブが押されているのか判断できます。

TabBar(
  onTap: (index) {
    final controller = scrollControllers[tabController.index]; // どのタブが押されたのか判断
    if (controller.hasClients) { // ScrollControllerがアタッチされているか確認
      controller.animateTo(
        0,
        duration: const Duration(milliseconds: 300),
        curve: Curves.linear,
      );
    }
  },
)

ここで重要なのが、controller.hasClientsです。

controller.hasClientsとは、ScrollController が少なくとも1つのスクロールビューに関連付けられているかどうかを確認するプロパティです。

それが関連付けられているなら、onTapした際に処理しても問題ないよね?が上記の処理内容になります。

flutterは奥が深い。。。
面白いですね。

以上!

Discussion