tabBottom页在切换时保持状态(keepalive),但在某些特殊情况下可以使其不保存状态以达到刷新效果
例如:购物车。正常使用购物车,需要保持页面状态,但在新的商品加入购物车后,需要重新获取购物车列表
首页
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('home build');
return Scaffold(
body: Center(child: Text('首页'),),
);
}
}
购物车页
import 'package:flutter/material.dart';
class ShoppingCart extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('ShoppingCart build');
return Scaffold(
body: Center(child: Text('购物车页'),),
);
}
}
tabBottom页
import 'package:flutter/material.dart';
import 'package:learn/pages/home.dart';
import 'package:learn/pages/shoppingCart.dart';
class TabBottom extends StatefulWidget {
@override
_TabBottomState createState() => _TabBottomState();
}
class _TabBottomState extends State<TabBottom> {
//页面列表
List pages = [
Home(),
ShoppingCart(),
];
//页面控制器
PageController _pageController = PageController();
//当前页面index,监听
ValueNotifier<int> _selectIndex = ValueNotifier(0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView.builder(
controller: _pageController,
onPageChanged: (index){
_selectIndex.value = index;
},
itemBuilder: (ctx,index){
return pages[index];
}
),
bottomNavigationBar: ValueListenableBuilder(
valueListenable: _selectIndex,
builder: (context,value,child){
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home),label: '首页'),
BottomNavigationBarItem(icon: Icon(Icons.shopping_cart),label: '购物车'),
],
selectedItemColor: Colors.blue,
unselectedItemColor: Color(0xff666666),
backgroundColor: Colors.white,
currentIndex: value,
onTap: (index){
_pageController.jumpToPage(index);
},
);
},
),
);
}
}
效果
每次点击切换页面,都会触发build方法,无法达到保存状态的要求
1.在购物车页混入AutomaticKeepAliveClientMixin(要使用StatefulWidget,且在State中混入)
2.重写wantKeepAlive 并返回true
3.build中添加super.build(context);
import 'package:flutter/material.dart';
class ShoppingCart extends StatefulWidget {
@override
_ShoppingCartState createState() => _ShoppingCartState();
}
class _ShoppingCartState extends State<ShoppingCart> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context);
print('ShoppingCart build');
return Scaffold(
body: Center(child: Text('购物车页'),),
);
}
@override
bool get wantKeepAlive => true;
}
效果
购物车页只会build一次,后续切换不会再执行build
1.创建布尔变量 _wantKeepAlive
2.将_wantKeepAlive赋值给重写的wantKeepAlive
3.触发修改_wantKeepAlive的方法,并调用updateKeepAlive(重点,必须调用,否则无效)
购物车
import 'package:flutter/material.dart';
class ShoppingCart extends StatefulWidget {
@override
_ShoppingCartState createState() => _ShoppingCartState();
}
class _ShoppingCartState extends State<ShoppingCart> with AutomaticKeepAliveClientMixin {
bool _wantKeepAlive = true;
@override
Widget build(BuildContext context) {
super.build(context);
print('ShoppingCart build');
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('购物车页'),
TextButton(onPressed: (){ _wantKeepAlive = false; this.updateKeepAlive(); }, child: Text('取消保持状态'))
],
),
),
);
}
@override
bool get wantKeepAlive => _wantKeepAlive;
}
方法有很多,推荐使用事件总线
总线
import 'package:event_bus/event_bus.dart';
EventBus eventBus = EventBus();
class ShoppingCarStateEvent{
bool wantKeepAlive;
ShoppingCarStateEvent({ bool wantKeepAlive = true, }){
this.wantKeepAlive = wantKeepAlive;
}
}
首页
import 'package:flutter/material.dart';
import 'package:learn/utils/event.dart';
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('home build');
return Scaffold(
body: Center(child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('首页'),
TextButton(onPressed: (){ eventBus.fire(ShoppingCarStateEvent(wantKeepAlive: false)); }, child: Text('取消购物车保持状态')),
],
)),
);
}
}
购物车
import 'package:flutter/material.dart';
import 'package:learn/utils/event.dart';
class ShoppingCart extends StatefulWidget {
@override
_ShoppingCartState createState() => _ShoppingCartState();
}
class _ShoppingCartState extends State<ShoppingCart> with AutomaticKeepAliveClientMixin {
bool _wantKeepAlive = true;
var _actionEventBus;
@override
void initState() {
//监听
_actionEventBus = eventBus.on<ShoppingCarStateEvent>().listen((event) {
print('wantKeepAlive状态变化:${event.wantKeepAlive}');
_wantKeepAlive = false;
this.updateKeepAlive();
});
super.initState();
}
@override
void dispose() {
_actionEventBus.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
print('ShoppingCart build');
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('购物车页'),
TextButton(onPressed: (){ _wantKeepAlive = false; this.updateKeepAlive(); }, child: Text('取消保持状态'))
],
),
),
);
}
@override
bool get wantKeepAlive => _wantKeepAlive;
}