在Flutter应用中,导航栏或Tab切换页面后默认情况下会丢失原页面状态,即每次进入页面时都会重新初始化状态,显然这样增加了额外的开销,并且带来了不好的用户体验。页面保持状态,不重绘,在app中很重要,比如看着朋友圈/热门微博,看到一半,需要切换到其他tab设置点东西,再切换回来,这个时候肯定不需要页面重绘,然后从头开始看吧,而是希望直接接着前面的状态继续看。
因此flutter 官方为我们提供解决方案 我们只需要在导航内需要保持页面状态的子页State中,继承AutomaticKeepAliveClientMixin并重写wantKeepAlive为true即可。
先看效果
Untitled.gif
第一步 新建 main
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TabBarPage(),
);
}
}
我们这里吧 TabBarPage单独抽离出来了
class TabBarPage extends StatefulWidget {
@override
_TabBarPageState createState() => _TabBarPageState();
}
class _TabBarPageState extends State<TabBarPage> with AutomaticKeepAliveClientMixin{
@override
bool get wantKeepAlive => true;
var _currentIndex = 0;
List titleList = ['首页','我的'];
final List <Widget> tabVC = [HomePage(),MyPage()];
PageController _pageController;
@override
void initState() {
// TODO: implement initState
super.initState();
this._pageController = PageController(initialPage: this._currentIndex);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
child: AppBar(
brightness: Brightness.light,
title: Text(titleList[this._currentIndex],
style: TextStyle(
color: Colors.black,//设置字体颜色
fontSize: 20,//设置字体大小
),
),
// backgroundColor: Colors.white,//设置导航背景颜色
elevation: 0,//隐藏底部阴影分割线
centerTitle: true,//标题
),
preferredSize: Size(double.infinity,44),
),
backgroundColor: Colors.white,
bottomNavigationBar: BottomNavigationBar(
currentIndex: this._currentIndex,
selectedItemColor: Colors.red,
unselectedItemColor: Colors.grey,
type:BottomNavigationBarType.fixed,
selectedLabelStyle: TextStyle(color: Colors.red),
unselectedLabelStyle: TextStyle(color: Colors.grey),
unselectedFontSize:14,
// selectedIconTheme: IconThemeData(),
elevation: 1,
onTap: (index){
this._pageController.jumpToPage(index);
},
iconSize: 30,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('首页')
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
title: Text('我的')
)
],
),
body:PageView(
physics: NeverScrollableScrollPhysics(),//禁止滑动
controller: this._pageController,
children: this.tabVC,
onPageChanged: (index){
setState(() {
_currentIndex =index;
});
},
)
);
}
}
我们在 Home页面需要实现 继承与 AutomaticKeepAliveClientMixin然后重写 bool get wantKeepAlive => true;
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context); //必须实现 不然 在push过后页面会刷新
return ListView.builder(
itemCount: 100,
itemBuilder: (context,index){
return ListTile(
title: Text('home$index'),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context){
return MyTest();
}));
},
);
}
);
}
}
在说一下一定要实现的
- with AutomaticKeepAliveClientMixin
- bool get wantKeepAlive => true;
- super.build(context); 一定要写,不然push 过后,页面还是会重置,我就是因为这句话没写苦恼了很久,差不多一个星期才搞定。。 在主页面一定要实现。
网友评论