事象
- タブ内のリストを特定位置までスクロールする。
- 表示しているタブから別のタブへ変更する。
- 前のタブに戻る。
- ★スクロール位置がリセットされている。
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();
},
),
]),
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の存在を知りました。