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;
}以上です