Flutter 在颤振页面视图中切换页面时丢失小部件状态
我在由PageController管理的PageView中有一系列有状态的小部件。我正在使用Flutter 在颤振页面视图中切换页面时丢失小部件状态,flutter,Flutter,我在由PageController管理的PageView中有一系列有状态的小部件。我正在使用pageController.jumpToPage(index)切换页面。切换页面时,小部件中的所有状态似乎都丢失了,就像从头开始重新创建一样。我曾尝试在PageController中使用keepPage:true,但似乎没有任何效果。这是页面浏览的预期行为还是我做错了什么?任何建议,谢谢 keepPage:true是默认行为;这意味着PageController将记住它所在的页面,如果它被销毁并重新创建
pageController.jumpToPage(index)
切换页面。切换页面时,小部件中的所有状态似乎都丢失了,就像从头开始重新创建一样。我曾尝试在PageController中使用keepPage:true
,但似乎没有任何效果。这是页面浏览的预期行为还是我做错了什么?任何建议,谢谢 keepPage:true
是默认行为;这意味着PageController
将记住它所在的页面,如果它被销毁并重新创建。这不是你想要的
相反,传递一个特定于页面构造函数的页面。这有助于为页面提供一个独特的存储桶。然后,在您希望恢复到以前状态的
状态中,您可以使用PageStorage.of(context)
获取存储桶,您可以从initState
中读取值,并在值更改时将值写入。您可以在中看到一个示例。与AutomaticEpaLiveClientMixin一起使用到您的子页面
然后@override
bool get wantKeepAlive=>true;
这是一个样本
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: [
new Tab(icon: new Icon(Icons.directions_car)),
new Tab(icon: new Icon(Icons.directions_transit)),
new Tab(icon: new Icon(Icons.directions_bike)),
new Tab(
icon: new Icon(Icons.airplanemode_active),
)
],
),
),
body: new TabBarView(children: [
new OnePage(color: Colors.black,),
new OnePage(color: Colors.green,),
new OnePage(color: Colors.red,),
new OnePage(color: Colors.blue,),
]),
),
);
}
}
class OnePage extends StatefulWidget {
final Color color;
const OnePage({Key key, this.color}) : super(key: key);
@override
_OnePageState createState() => new _OnePageState();
}
class _OnePageState extends State<OnePage> with AutomaticKeepAliveClientMixin<OnePage> {
@override
Widget build(BuildContext context) {
super.build(context);
return new SizedBox.expand(
child: new ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return new Padding(
padding: const EdgeInsets.all(10.0),
child: new Text(
'$index',
style: new TextStyle(color: widget.color),
),
);
},
),
);
}
@override
bool get wantKeepAlive => true;
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“颤振演示”,
主题:新主题数据(
主样本:颜色。蓝色,
),
主页:新MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
@凌驾
小部件构建(构建上下文){
返回DefaultTabController(
长度:4,
儿童:新脚手架(
appBar:新的appBar(
底部:新选项卡栏(
选项卡:[
新建选项卡(图标:新建图标(图标.方向\汽车)),
新建选项卡(图标:新建图标(图标.方向))),
新建选项卡(图标:新建图标(图标.方向),
新标签(
图标:新图标(图标。airplanemode_激活),
)
],
),
),
正文:新选项卡视图(子项:[
新一页(颜色:Colors.black,),
新的OnePage(颜色:Colors.green,),
新一页(颜色:Colors.red,),
新一页(颜色:Colors.blue,),
]),
),
);
}
}
类OnePage扩展了StatefulWidget{
最终颜色;
constOnePage({Key-Key,this.color}):super(Key:Key);
@凌驾
_OnePageState createState()=>new_OnePageState();
}
类_OnePageState使用AutomaticEpaLiveClientMixin扩展状态{
@凌驾
小部件构建(构建上下文){
super.build(上下文);
返回新的SizedBox.expand(
子项:新建ListView.builder(
物品计数:100,
itemBuilder:(上下文,索引){
返回新的填充(
填充:常数边集全部(10.0),
儿童:新文本(
“$index”,
样式:新文本样式(颜色:widget.color),
),
);
},
),
);
}
@凌驾
bool get wantKeepAlive=>true;
}
编写自定义小部件:
import 'package:flutter/material.dart';
class KeepAlivePage extends StatefulWidget {
KeepAlivePage({
Key key,
@required this.child,
}) : super(key: key);
final Widget child;
@override
_KeepAlivePageState createState() => _KeepAlivePageState();
}
class _KeepAlivePageState extends State<KeepAlivePage>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
/// Dont't forget this
super.build(context);
return widget.child;
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
import 'package:flutter/material.dart';
import 'keep_alive_page.dart';
class PageViewDemo extends StatefulWidget {
const PageViewDemo({Key key}) : super(key: key);
@override
_PageViewDemoState createState() => _PageViewDemoState();
}
class _PageViewDemoState extends State<PageViewDemo> {
@override
Widget build(BuildContext context) {
return PageView(
children: [
KeepAlivePage(child:Page1()),
KeepAlivePage(child: Page2()),
KeepAlivePage(child:Page3()),
],
);
}
}
导入“包装:颤振/材料.省道”;
类KeepAlivePage扩展StatefulWidget{
保留第页({
关键点,
@需要这个孩子,
}):super(key:key);
最后一个孩子;
@凌驾
_KeepAlivePageState createState()=>\u KeepAlivePageState();
}
类_KeepAlivePageState扩展状态
使用AutomaticEpaLiveClientMixin{
@凌驾
小部件构建(构建上下文){
///别忘了这个
super.build(上下文);
返回widget.child;
}
@凌驾
//TODO:实现wantKeepAlive
bool get wantKeepAlive=>true;
}
并在页面视图中使用:
import 'package:flutter/material.dart';
class KeepAlivePage extends StatefulWidget {
KeepAlivePage({
Key key,
@required this.child,
}) : super(key: key);
final Widget child;
@override
_KeepAlivePageState createState() => _KeepAlivePageState();
}
class _KeepAlivePageState extends State<KeepAlivePage>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
/// Dont't forget this
super.build(context);
return widget.child;
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
import 'package:flutter/material.dart';
import 'keep_alive_page.dart';
class PageViewDemo extends StatefulWidget {
const PageViewDemo({Key key}) : super(key: key);
@override
_PageViewDemoState createState() => _PageViewDemoState();
}
class _PageViewDemoState extends State<PageViewDemo> {
@override
Widget build(BuildContext context) {
return PageView(
children: [
KeepAlivePage(child:Page1()),
KeepAlivePage(child: Page2()),
KeepAlivePage(child:Page3()),
],
);
}
}
导入“包装:颤振/材料.省道”;
导入'keep_alive_page.dart';
类PageViewDemo扩展StatefulWidget{
constpageviewdemo({Key}):super(Key:Key);
@凌驾
_PageViewDemoState createState()=>\u PageViewDemoState();
}
类_PageViewDemoState扩展状态{
@凌驾
小部件构建(构建上下文){
返回页面视图(
儿童:[
KeepAlivePage(子项:Page1()),
KeepAlivePage(子项:Page2()),
KeepAlivePage(子项:Page3()),
],
);
}
}
需要这样做似乎有些奇怪。所以我应该保存页面视图中每个小部件的滚动位置,或者导航堆栈(如果存在)之类的东西?有没有一种方法可以让小部件保持在我翻页时的状态?我应该提到的是,我的PageView中的一个小部件在你翻页时不会失去它的状态,因此可能只是我在做一些总体上愚蠢的事情。滚动位置由框架内部维护,请参阅中的PageStorage
的用法。如果保持其他状态,可能是因为它存储在树的更高级别。谢谢,为包含ListView的小部件设置PageStorage键似乎已经完成了保存滚动位置的技巧。我必须承认,我仍然很困惑,为什么手动存储状态的一部分是必要的,而状态的其余部分是如此惊人的自动。我想我不明白为什么StatefulWidget创建的状态对象不只是存储然后自动重用。PageViews可能有无限的页面,因此Flatter需要一些机制来清理屏幕外的页面。我知道PageView可以有多个页面,与ViewPager类似,但ViewPager提供了一个函数,您可以在该函数中定义要访问的页面数