LoginSignup
16
12

More than 3 years have passed since last update.

【Flutter】タブを移動するとListViewのスクロール位置がリセットされる

Posted at

事象

  1. タブ内のリストを特定位置までスクロールする。
  2. 表示しているタブから別のタブへ変更する。
  3. 前のタブに戻る。
  4. ★スクロール位置がリセットされている。

output.gif

class SamplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(),
        body: Column(
          children: <Widget>[
            TabBar(
              tabs: [
                Tab(child: Text("タブ1", style: TextStyle(color: Colors.black))),
                Tab(child: Text("タブ2", style: TextStyle(color: Colors.black))),
              ],
            ),
            Expanded(
              child: TabBarView(children: [
                ListView.separated(
                  itemCount: 50,
                  itemBuilder: (context, index) {
                    return ListTile(title: Text("アイテム${index.toString()}"));
                  },
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                ),
                ListView.separated(
                  itemCount: 50,
                  itemBuilder: (context, index) {
                    return ListTile(title: Text("アイテム${index.toString()}"));
                  },
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                ),
              ]),
            ),
          ],
        ),
      ),
    );
  }
}

対応

ListViewのkeyにPageStorageKeyを追加します。

一部抜粋
child: TabBarView(children: [
  ListView.separated(
    // ***ここです!***
    key: PageStorageKey(0),
    itemCount: 50,
    itemBuilder: (context, index) {
      return ListTile(title: Text("アイテム${index.toString()}"));
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
  ),
  ListView.separated(
    // ***ここです!***
    key: PageStorageKey(1),
    itemCount: 50,
    itemBuilder: (context, index) {
      return ListTile(title: Text("アイテム${index.toString()}"));
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
  ),
]),

output.gif

PageStorageKeyの説明にはこう記載されています。

A [ValueKey] that defines where [PageStorage] values will be saved.

[Scrollable]s ([ScrollPosition]s really) use [PageStorage] to save their
scroll offset. Each time a scroll completes, the scrollable's page
storage is updated.

つまり、スクロール位置はPageStorageに保存されており、その保存場所を指定するのがPageStorageKeyである、ということになります。
スクロール位置の保存場所を指定することで、引き出すこともできるようになったということですね。

参考

https://codeday.me/jp/qa/20190504/770454.html
こちらの記事でPageStorageKeyの存在を知りました。

16
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12