一、问题说明
我们在 Android 开发的时候经常会用到 Tab + ViewPager 的页面模式,同样的,Flutter 也提供了这样的开发模式,但不同的是: Android 中的 ViewPager 提供了保留页面状态的支持,而 Flutter 的 TabController 却没有提供,这样的话每次点击 Tab 或左右滑动页面后都会触发重新构建渲染,我们在 initState() 中写的网络请求也会重复请求,这样的用户体验是很不好的 !
二、解决方案
- 子页面继承自 StatefulWidget
- State 需要继承自 AutomaticKeepAliveClientMixin
- 重写 get wantKeepAlive 方法,并返回 true
代码示例:
1、父页面
class OrderListContainerPage extends Widget {
OrderListContainerPage({Key key}) : super(key: key);
@override
BaseState createState() {
return _OrderListContainerPageState();
}
}
class _OrderListContainerPageState extends State<OrderListContainerPage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: TabBar(
tabs: <Widget>[
Tab(child: Tab(text: 'tab1',),),
Tab(child: Tab(text: 'tab2',),),
Tab(child: Tab(text: 'tab3',),),
],
),
),
body: TabBarView(
children: <Widget>[
OrderListPage(),
OrderListPage(),
OrderListPage(),
],
),
),
);
}
}
2、子页面
class OrderListPage extends StatefulWidget {
OrderListPage({
Key key,
}) : super(key: key);
@override
State createState() {
return _OrderListPageState();
}
}
class _OrderListPageState extends BaseState<OrderListPage> with AutomaticKeepAliveClientMixin{
@override
Widget build(BuildContext context) {
return Text('Hello World');
}
@override
bool get wantKeepAlive => true;
}
从代码中可以看出:最关键的:继承自 AutomaticKeepAliveClientMixin 和重写 wantKeepAlive 方法。
三、补充注意点
如果你的页面是以下情况需要注意了:
- 继承自父页面。
- 在父页面中重写了 build 方法去构建公共元素,并向子页面开放了新的 buildChild(名字不一定是这个名字,只是举个例子) 类似功能方法。
- 子页面一般是重写父页面的 buildChild 去构建子元素。
如果你是以上情况,需要注意,必须重写其 build 方法,因为继承自 AutomaticKeepAliveClientMixin 后 build 方法就不是父页面的那个 build 了。 如果不重写的话会直接报红:build 不能返回 Null 类型。
搞定 !