Flutter Error| A dismissed Dimissible widget is still part of the tree

2022/05/08に公開

FlutterでDismissible Widgetで、スワイプによる削除を実装したところ、
A dismissed Dismissible widget is still part of the tree. Make sure to implement the onDismissed handler and to immediately remove the Dismissible widget from the application once that handler has fired. Se also: https://flutter.dev/docs/testing/errors
というエラーが発生した。

Dismissible WidgetのonDismissedで、

onDismissed: (direction) {
  if (direction == DismissDirection.endToStart) {
    history.delete();
  }
},

のように削除できるようにする。historyは次のようにHiveObjectをextendsしたクラスインスタンス。

class HistoryHive extends HiveObject {
 // 省略
}

どうやら、

  
  Widget build(BuildContext context, WidgetRef ref) {
    return ValueListenableBuilder<Box<HistoryHive>>(
      valueListenable: Boxes.getHistories().listenable(),
      builder: (context, box, _) {
        final histories = box.values.toList().cast<HistoryHive>();

        if (histories.isEmpty) {
          return const Text("History is empty");
        } else {
          return ListView.builder(
            itemCount: histories.length,
            itemBuilder: (context, i) {
              final history = histories[i];
              return Dismissible(
                key: Key(i.toString()),
                child: Container()
		:
		省略

のように、KeyをKey(i.toString())としていたが、削除後、同じキーが他のWidgetに使われてしまい、キーが消せない。そのため、"still part of the tree"というエラーが発生していた模様。

Dismissible(
	key: UniqueKey(),

と、UniqueKey()を割り当てることで同じキーが使いまわされることはなくなり、エラーは消えた。

参考

Discussion