17.请求数据保留
前文中可以发现一个问题,每次切换页面,都会重新请求数据。而实际开发中,我们会对数据进行保留,在需要的时候再进行数据更新。

1
多继承
AutomaticKeepAliveClientMixin
class MessagePage extends StatefulWidget {
@override
_MessagePageState createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> with AutomaticKeepAliveClientMixin<MessagePage> {
...
}
class _MessagePageState extends State<MessagePage> with AutomaticKeepAliveClientMixin<MessagePage> {
...
@override
bool get wantKeepAlive => true;
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(...);
}
原先我们的切换Tab的逻辑是这样的:
class _MyHomePageDataSource extends State<MyHomePage> {
int _selectedTab = 0;
final List<Widget> _pages = [
MessagePage(),
ContactsPage(),
MommentPage(),
MinePage()
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_selectedTab],
...
);
并非所有的子页面的
widget
都在标签容器的 widget
树中,导致每次切换都会去重新生成渲染。- 我们需要做如下调整:
- 构建
PageController
- 调整
Body
为PageView
, 并绑定PageController
和pages
- 通过
PageController
切换子页面
class _MyHomePageDataSource extends State<MyHomePage> {
int _selectedTab = 0;
final List<Widget> _pages = [
MessagePage(),
ContactsPage(),
MommentPage(),
MinePage()
];
// 一、 构建 PageController
final PageController _pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
// 二、 调整 Body 为 PageView, 并绑定 PageController 和 pages
body: PageView(
controller: _pageController,
children: _pages,
),
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Colors.green,
unselectedItemColor: Colors.grey,
currentIndex: _selectedTab,
onTap: (idx) {
setState(() {
_selectedTab = idx;
// 三、 通过 PageController 切换子页面
_pageController.jumpToPage(_selectedTab);
});
},
items: const [...],
),
);
}
}

1

2
在使用总突然发现可以通过滑动切换 PageView 的子页面。但是底部的标签选中没有变化,下面我们来处理一下。
通过 onPageChanged 来监听页面的切换,同步修改选中标签。
body: PageView(
onPageChanged: (idx) {
setState(() {
_selectedTab = idx;
});
},
controller: _pageController,
children: _pages,
),
当然,不需要滑动的话可以通过 physics 来进行关闭。
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
children: _pages,
),
Last modified 1yr ago