Flutter PageView 自由控制状态保持
  xx2YH4ad7R0N 2023年11月02日 53 0


需求

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方法,无法达到保存状态的要求

Flutter PageView 自由控制状态保持_flutter

保持状态

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

Flutter PageView 自由控制状态保持_ide_02

控制组件的状态是否保持

组件内控制

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;
}

效果
点击按钮后,购物车页的build重新打印

Flutter PageView 自由控制状态保持_android_03

组件外控制

方法有很多,推荐使用事件总线

总线

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;
}

效果
第一次切换购物车页面后,不在触发build,点击首页的按钮后,在进入购物车页面,会又触发build

Flutter PageView 自由控制状态保持_ide_04

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  4koL3J55wyKx   2023年11月13日   38   0   0 icogitCentOS
  iD7FikcuyaVi   2023年11月30日   26   0   0 MacWindowsandroid
  b1UHV4WKBb2S   2023年11月13日   29   0   0 flutterDart
  zSWNgACtCQuP   2023年11月13日   32   0   0 ide
xx2YH4ad7R0N