🤖

Flutter で ListView の widget を破棄させたくない!

2024/04/30に公開

死ぬほど今更感がありますが
ListView で widget を破棄させない方法があったので備忘録がてら残しますmm

結論は破棄したくないウィジェットを
StatefullWidget で管理をして AutomaticKeepAliveClientMixin で破棄させないっていうやり方ですね

先にコード貼り付けておきます。

dart
class _Test extends StatelessWidget {
  const _Test({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Builder(
          builder: (context) => Scaffold(
            body: ListView(
              children: [
                for (var i = 0; i < 1000; i++) const _Item(),
              ],
            ),
          ),
        ),
      );
}

class _Item extends StatefulWidget {
  const _Item({super.key});

  @override
  State<_Item> createState() => _ItemState();
}

class _ItemState extends State<_Item> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) => const Text('テキスト');

  @override
  bool get wantKeepAlive => true;
}

これを動かした時の動画です
https://youtu.be/Yaf7K94XILs

なぜ今になって?

そう、これをなぜ今になって調べたかというと
投稿のタイムラインでいいね機能を付ける必要が出てきたからですね

このいいねをどうやって取得するのか考えていましたが
全体を描画する前に1つずつ取得するとかなり時間かかるなと思ったんですよね
(whereIn 使ったら10個ずつ取得できるので時短になるとかは一旦考えません)

じゃあ一旦投稿を描画して、その後にいいねを取得したら良いのでは?
みたいな考えになったんです。

ただ ListView ってスクロールし過ぎると
投稿自体が dispose されるからいいね自体も dispose されて
また描画されたときに再取得みたいなことになってしまう。

だから ListView を使ってるけど dispose されない方法を探していたっていう感じですね

ただ、やってみて思ったのは投稿を描画後にいいねを取得するっていうのは
ちょっと微妙かもですねぇ

Discussion