はじめに
Tab + ListViewの画面構成時に Widget の状態 (State) を保存する方法をまとめておきます。
[方法その1] PageStorageKeyを利用
Widget のKey
にPageStorageKey
のインスタンスを指定するだけです。PageStorageKey
自体についての解説はこちらを参照してください。
サンプルコード
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
bottom: TabBar(
tabs: <Widget>[
Tab(
child: Text('Tab-1'),
),
Tab(
child: Text('Tab-2'),
),
],
),
),
body:
TabBarView(
children: <Widget>[
// Stateが保存されないパターン
//_TabPage(tab: 0),
//_TabPage(tab: 1),
// PageStorageKeyを利用してStateを保存するパターン
_TabPage(key: PageStorageKey(0), tab: 0),
_TabPage(key: PageStorageKey(1), tab: 1),
],
),
),
);
}
}
class _TabPage extends StatefulWidget {
_TabPage({Key key, this.tab}) : super(key: key);
final int tab;
@override
_TabPageState createState() => _TabPageState();
}
class _TabPageState extends State<_TabPage> {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title:
Text('${widget.tab}: Item $index'),
);
},
);
}
}
[方法その2] AutomaticKeepAliveClientMixinを利用
PageStorageKey
を使わず、Stateインスタンスに対してAutomaticKeepAliveClientMixinをMix-inすることでもいけます。
ソースコードはこちら
編集箇所
class _TabPageState extends State<_TabPage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true; // 追加!
@override
Widget build(BuildContext context) {
super.build(context); // 追加!
サンプルコード
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
bottom: TabBar(
tabs: <Widget>[
Tab(
child: Text('Tab-1'),
),
Tab(
child: Text('Tab-2'),
),
],
),
),
body:
TabBarView(
children: <Widget>[
// AutomaticKeepAliveClientMixinを利用してStateを保存するパターン
_TabPage(tab: 0),
_TabPage(tab: 1),
],
),
),
);
}
}
class _TabPage extends StatefulWidget {
_TabPage({Key key, this.tab}) : super(key: key);
final int tab;
@override
_TabPageState createState() => _TabPageState();
}
class _TabPageState extends State<_TabPage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true; // 追加!
@override
Widget build(BuildContext context) {
super.build(context); // 追加!
return ListView.builder(
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title:
Text('${widget.tab}: Item $index'),
);
},
);
}
}