Flutter PageView 自由控制状态保持
Posted 一叶飘舟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter PageView 自由控制状态保持相关的知识,希望对你有一定的参考价值。
需求
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;
效果
点击按钮后,购物车页的build重新打印
组件外控制
方法有很多,推荐使用事件总线
总线
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 自由控制状态保持的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中创建垂直滚动的 PageView?
在垂直PageView中包装不同高度的项目 - Flutter