微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter:当父母的状态改变时,子小部件的状态会丢失

如何解决Flutter:当父母的状态改变时,子小部件的状态会丢失

我正在学习 Flutter 并且正在努力解决一些状态管理问题。

我有一个 HomeScreen 小部件,其中包含 Scaffold 和一个 BottomNavigationBar。要根据BottomNavigationBar 中选定的选项卡切换页面,我将PageView 与PageController 一起使用。以下是 HomeScreen 小部件的 build 方法的外观:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: _currentIndex == 2,appBar: AppBar(...properties),body: PageView(
        controller: _pageController,children: _pages,),bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[...items],currentIndex: _currentIndex,onTap: _onItemTapped,//This changes state _currentIndex and calls the method _pageController.jumpToPage(_currentIndex);
      ),);
  }
  • _currentIndex 最初为 0。
  • _pages一个包含 3 个小部件的列表。
  • _pageController一个简单的 PageController,initialPage 设置为 0。

如果您注意到我正在使用使用 extendBodyBehindAppBar: _currentIndex == 2 状态的属性 _currentIndex,这会导致问题。 当我点击 BottomNavigationBar 上的最后一个 Tab 时,状态 _currentIndex 更改为 2,因此 extendBodyBehindAppBar 设置为 true,这使得整个 Scaffold 重建自身,PageView 的状态为丢失了。

如果注释掉 extendBodyBehindAppBar: _currentIndex == 2 行,那么即使 Scaffold 重建了 PageView 小部件的状态。

据我所知,即使父级重建,Flutter 也应该保持子级 Widgets 的状态,因为 WidgetTree 没有改变或重新排列。我尝试在 PageView 上使用 Key 但没有任何效果

非常感谢任何帮助。

解决方法

参考Lucas Salton Cardinali post on medium 你需要使用PageStorage来持久化你需要的child被销毁后的状态。

这里是从同一页面检索的示例:

import 'package:flutter/material.dart';

// ...

void main() => runApp(MyApp());

// ...

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<Widget> pages = <Widget>[
    ColorBoxPage(
      key: PageStorageKey('pageOne'),),ColorBoxPage(
      key: PageStorageKey('pageTwo'),)
  ];
  int currentTab = 0;
  final PageStorageBucket _bucket = PageStorageBucket();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Persistence Example"),body: PageStorage(
        child: pages[currentTab],bucket: _bucket,bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentTab,onTap: (int index) {
          setState(() {
            currentTab = index;
          });
        },items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),label: 'page 1',BottomNavigationBarItem(
            icon: Icon(Icons.settings),label: 'page2',],);
  }
}

class ColorBoxPage extends StatelessWidget {
  ColorBoxPage({
    Key? key,}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemExtent: 250.0,itemBuilder: (context,index) => Container(
        padding: EdgeInsets.all(10.0),child: Material(
          color: index % 2 == 0 ? Colors.cyan : Colors.deepOrange,child: Center(
            child: Text(index.toString()),);
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?