flutter TabBarViewでListViewを使う
https://qiita.com/Dreamwalker/items/cc19bb4f8b7068ae0fd3
この辺りを参考にタブバーを試していたが、タブを切り替えるたびにTabBarViewのchildrenにセットしたWidgetがinitStateされてしまってListViewが毎回作られてしまった。DefaultTabController使って、StatefulWidgetにはAutomaticKeepAliveClientMixinを適用させてbool get wantKeepAlive => trueするといいらしい。
import 'package:flutter/material.dart'; import 'dart:async'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: TabBarDemo(), ); } } class TabBarDemo extends StatelessWidget { final List<Tab> myTabs = <Tab>[ Tab(text: 'LEFT'), Tab(text: 'RIGHT'), ]; final List<_MyContent> myContents = <_MyContent>[ _MyContent(), _MyContent(), ]; @override Widget build(BuildContext context) { return DefaultTabController( length: myTabs.length, child: Scaffold( appBar: AppBar( title: Text("TabBarSample"), bottom: TabBar(tabs: myTabs), ), body: TabBarView(children: myContents), ), ); } } class _MyContent extends StatefulWidget { _MyContentState _state = _MyContentState(); @override State<StatefulWidget> createState() { return _state; } } class _MyContentState extends State<_MyContent> with AutomaticKeepAliveClientMixin { List<String> items = []; @override Widget build(BuildContext context) { return Scaffold( body: RefreshIndicator( child: ListView.builder( itemBuilder: (context, index) { if (index == items.length) { _load(); return Center(child: CircularProgressIndicator()); } else if (items.length < index) { return null; } else { return Container( child: ListTile(title: Text(items[index])), ); } }, ), onRefresh: refresh, ) ); } void _load() async { await new Future.delayed(const Duration(seconds: 1)); setState(() { var s = items.length; for (var i = 0; i < 20; i++) { items.add("アイテム${s + i}"); } }); } Future<void> refresh() { return Future.sync(() { setState(() { items.clear(); _load(); }); }); } @override bool get wantKeepAlive => true; }
以上です