「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」
Hi 👋
- Wechat: RyukieW
- 微信公众号:LabLawliet
- 📦 技术文章归档
- 🐙 Github
| 我的个人项目 | 扫雷Elic 无尽天梯 | 梦见账本 | 隐私访问记录 |
|---|---|---|---|
| 类型 | 游戏 | 财务 | 工具 |
| AppStore | Elic | Umemi | 隐私访问记录 |
Flutter小技巧|从侧索引条封装看手势处理与clamp函数
前言
前文Flutter小技巧|第三方库导入与网络数据展示(三种形式)中可以发现一个问题,每次切换页面,都会重新请求数据。而实际开发中,我们会对数据进行保留,在需要的时候再进行数据更新。
Mixin
调整继承关系
多继承 AutomaticKeepAliveClientMixin
class MessagePage extends StatefulWidget {
@override
_MessagePageState createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> with AutomaticKeepAliveClientMixin<MessagePage> {
...
}
重写 wantKeepAlive
class _MessagePageState extends State<MessagePage> with AutomaticKeepAliveClientMixin<MessagePage> {
...
@override
bool get wantKeepAlive => true;
}
调整 build 方法
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(...);
}
调整 MyHomePage (标签Tab页)
原先我们的切换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 [...],
),
);
}
}
检查效果
PageView
滑动切换子页面
在使用总突然发现可以通过滑动切换 PageView 的子页面。但是底部的标签选中没有变化,下面我们来处理一下。
同步标签切换
通过 onPageChanged 来监听页面的切换,同步修改选中标签。
body: PageView(
onPageChanged: (idx) {
setState(() {
_selectedTab = idx;
});
},
controller: _pageController,
children: _pages,
),
关闭滑动切换
当然,不需要滑动的话可以通过 physics 来进行关闭。
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: _pageController,
children: _pages,
),