当前位置: 首页 > 知识库问答 >
问题:

当使用BottomNavigationBar导航时,如何在flutter中保持小部件的状态?

归鹤龄
2023-03-14

我目前正在开发一个Flutter应用程序,它将在使用BottomNavigationBar时,在从一个屏幕导航到另一个屏幕,然后再返回时保留状态。就像它在Spotify移动应用程序中一样;如果您在某个主屏幕上向下导航到导航层级中的某个级别,通过底部导航栏更改屏幕,然后再更改回旧屏幕,将会保留用户在该层级中的位置,包括状态的保留。

我把头靠在墙上,尝试各种不同的事情,但没有成功。

我想知道如何防止< code>pageChooser()中的页面在用户点击BottomNavigationBar项后被切换时重新构建,而是保留它们已经处于的状态(页面都是有状态的小部件)。

import 'package:flutter/material.dart';
import './page_plan.dart';
import './page_profile.dart';
import './page_startup_namer.dart';

void main() => runApp(new Recipher());

class Recipher extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Pages();
  }
}

class Pages extends StatefulWidget {
  @override
  createState() => new PagesState();
}

class PagesState extends State<Pages> {
  int pageIndex = 0;


  pageChooser() {
    switch (this.pageIndex) {
      case 0:
        return new ProfilePage();
        break;

      case 1:
        return new PlanPage();
        break;

      case 2:
        return new StartUpNamerPage(); 
        break;  

      default:
        return new Container(
          child: new Center(
            child: new Text(
              'No page found by page chooser.',
              style: new TextStyle(fontSize: 30.0)
              )
            ),
          );     
    }
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        body: pageChooser(),
        bottomNavigationBar: new BottomNavigationBar(
          currentIndex: pageIndex,
          onTap: (int tappedIndex) { //Toggle pageChooser and rebuild state with the index that was tapped in bottom navbar
            setState(
              (){ this.pageIndex = tappedIndex; }
              ); 
            },
          items: <BottomNavigationBarItem>[
            new BottomNavigationBarItem(
              title: new Text('Profile'),
              icon: new Icon(Icons.account_box)
              ),
              new BottomNavigationBarItem(
                title: new Text('Plan'),
                icon: new Icon(Icons.calendar_today)
              ),
                new BottomNavigationBarItem(
                title: new Text('Startup'),
                icon: new Icon(Icons.alarm_on)
              )
            ],
          )
      )
    );
  }
}

共有3个答案

西门品
2023-03-14

使用“自动保留”“通知”中新强制不处置选项卡内容。

class PersistantTab extends StatefulWidget {
  @override
  _PersistantTabState createState() => _PersistantTabState();
}

class _PersistantTabState extends State<PersistantTab> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  // Setting to true will force the tab to never be disposed. This could be dangerous.
  @override
  bool get wantKeepAlive => true;
}

为了确保选项卡在不需要持久化时得到释放,请使wantKeepAlive返回一个类变量。您必须调用updateKeepAlive()来更新keep-alive状态。

动态保持活动的示例:

// class PersistantTab extends StatefulWidget ...

class _PersistantTabState extends State<PersistantTab>
    with AutomaticKeepAliveClientMixin {
  bool keepAlive = false;

  @override
  void initState() {
    doAsyncStuff();
  }

  Future doAsyncStuff() async {
    keepAlive = true;
    updateKeepAlive();
    // Keeping alive...

    await Future.delayed(Duration(seconds: 10));

    keepAlive = false;
    updateKeepAlive();
    // Can be disposed whenever now.
  }

  @override
  bool get wantKeepAlive => keepAlive;

  @override
  Widget build(BuildContext context) {
    super.build();
    return Container();
  }
}
裴宏壮
2023-03-14

晚会迟到了,但我有一个简单的解决办法。将PageView小部件与AutomaticKeepAliveClinetMixin配合使用。

它的美妙之处在于,在你点击它之前,它不会加载任何选项卡。

包含BottomNavigationBar的页面:

var _selectedPageIndex;
List<Widget> _pages;
PageController _pageController;

@override
void initState() {
  super.initState();

  _selectedPageIndex = 0;
  _pages = [
    //The individual tabs.
  ];

  _pageController = PageController(initialPage: _selectedPageIndex);
}

@override
void dispose() {
  _pageController.dispose();

  super.dispose();
}

@override
Widget build(BuildContext context) {
  ...
    body: PageView(
      controller: _pageController,
      physics: NeverScrollableScrollPhysics(),
      children: _pages,
    ),
   bottomNavigationBar: BottomNavigationBar(
      ...
      currentIndex: _selectedPageIndex,
      onTap: (selectedPageIndex) {
        setState(() {
          _selectedPageIndex = selectedPageIndex;
          _pageController.jumpToPage(selectedPageIndex);
        });
      },
  ...
}

单个选项卡:

class _HomeState extends State<Home> with AutomaticKeepAliveClientMixin<Home> {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    //Notice the super-call here.
    super.build(context);
    ...
  }
}

我在这里做了一个关于它的视频。

澹台衡
2023-03-14

要将状态保持在BottomNavigationBar中,可以使用IndexedStack

    @override
      Widget build(BuildContext context) {
        return Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            onTap: (index) {
              setState(() {
                current_tab = index;
              });
            },
            currentIndex: current_tab,
            items: [
              BottomNavigationBarItem(
                ...
              ),
              BottomNavigationBarItem(
                ...
              ),
            ],
          ),
          body: IndexedStack(
            children: <Widget>[
              PageOne(),
              PageTwo(),
            ],
            index: current_tab,
          ),
        );
      }

 类似资料:
  • 本文向大家介绍Android BottomNavigationBar底部导航的使用方法,包括了Android BottomNavigationBar底部导航的使用方法的使用技巧和注意事项,需要的朋友参考一下 简介:Google推出的BottomNavigationBar底部导航栏 1 、基本的使用(add和replace方式) 2、扩展添加消息和图形 3、修改图片大小与文字间距 版本更新:2019

  • 本文向大家介绍Android使用BottomNavigationBar实现底部导航栏,包括了Android使用BottomNavigationBar实现底部导航栏的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android实现底部导航栏的具体代码,供大家参考,具体内容如下 展示 MODE_FIXED+BACKGROUND_STYLE_STATIC效果 DE_FIXED+BACKGR

  • 当我使用底部导航进行导航时,碎片会被破坏,计时器会重置到00:00。我用过计时器。我尝试了RetainInstance=true,但它只在屏幕旋转时才有帮助。 mainactivity.kt TimerFragment.kt

  • 我在我的android应用程序中使用导航抽屉,当我重新选择片段时,它会加载两次。 以下是我的代码 在每个片段中,我都使用异步任务,当我选择片段时,异步任务一次又一次地启动 请帮助我

  • 我注意到当打开我的应用程序时,有两个屏幕可以到达我的第一个颤动屏幕 1-1屏幕有灰色或(50%透明)状态和导航栏黑色和浅色图标。2-2屏幕有100%透明的状态和导航栏和白色图标。 我怎么能让所有的屏幕像第一次颤动屏幕100透明状态和导航栏与黑色图标(亮度暗)。 第一屏 第二屏 第一个颤振筛 风格xml 主要活动。kt 编辑 现在我已经改变了我的代码,第一个屏幕是正确的,但第二个屏幕仍然图标是白色的

  • 问题内容: 我试图在ES6中使用有状态的React组件,但是当我定义一个构造函数时,在多次渲染该组件(从其父对象)时,构造函数将仅被调用一次。示例如下所示。 这不会更新渲染的输出(它将始终为),但是日志将输出: 这是一个JSFiddle:http : //jsfiddle.net/jor0xu1a/1/ 我知道该示例不需要状态,但是我尝试使其尽可能简单以显示我的问题。 我想念什么? 问题答案: 我