首页 > 解决方案 > 如何使用存储选项卡当前状态的底部导航栏在选项卡中建立导航/页面?

问题描述

我的问题

我想使用 BottomNavigation 并且我还想保留当前导航(我想使用多个页面,包括导航和属于脚手架的所有内容)和选择。需要使用 PopUpMenu 并关闭外部 Scaffold(“外部脚手架”在下一段中解释) - 由于注销功能而关闭。在脚手架中使用脚手架不允许我从内部关闭外部脚手架。另一个问题是,Android 有后退按钮。如果您按下此按钮,应用程序将关闭,因为“backbutton-pressed-event”(由 Widget WillPopScope 捕获)关闭了整个应用程序,因为从 android 按下此后退按钮只会影响外部脚手架,但此按钮应该有效在选项卡中导航的内部。

当前方式

我正在为 BottomNavigationBarTab (PersistentTabs) 使用预定义的类来存储当前的选项卡情况。目前我正在使用脚手架作为基础。我也在为标签页使用脚手架,所以它是脚手架中的脚手架,这会导致我上面描述的问题。所以我解决了关闭应用程序的问题,方法是使用 WillPopScope 按下 android 的后退箭头并存储选项卡的当前页面。但我仍然无法从内部 Scaffold (选项卡中的页面)关闭应用程序。

基础脚手架

带有底部导航和控件的页面

Test.shouldPop 是一个 int,它应该可以帮助我检查是否可以关闭外部 Scaffold。

WillPopScope(
      onWillPop: () async {
        if(Test.shouldPop == 0 || currentTabIndex == 0 || currentTabIndex == 2) {
          return true;
        }
        return false;
      },
      child: Scaffold(
        body: PersistentTabs(
          currentTabIndex: currentTabIndex,
          screenWidgets: [NotesHome(uid: widget.uid), AreaOverviewPage(uid: widget.uid), StatisticsHome()],
        ),
        bottomNavigationBar: BottomNavigationBar(
          selectedItemColor: AppColors.mainAccent,
          onTap: setCurrentIndex,
          currentIndex: currentTabIndex,
          items: [
            BottomNavigationBarItem(),
            BottomNavigationBarItem(),
            BottomNavigationBarItem(),
          ],
        ),
      ),
    )

持久选项卡类

class PersistentTabs extends StatelessWidget {
  const PersistentTabs({@required this.screenWidgets, this.currentTabIndex = 0});
  final int currentTabIndex;
  final List<Widget> screenWidgets;

  List<Widget> _buildOffstageWidgets() {
    return screenWidgets
        .map(
          (w) => Offstage(
        offstage: currentTabIndex != screenWidgets.indexOf(w),
        child: Navigator(
          onGenerateRoute: (routeSettings) {
            return MaterialPageRoute(builder: (_) => w);
          },
        ),
      ),
    )
        .toList();
  }
  
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: _buildOffstageWidgets(),
    );
  }
}

示例第 1 页

此页面是此选项卡的主页。

Widget build(BuildContext context){
    Test.shouldPop = 0;

    double screenHeight = MediaQuery.of(context).size.height - 80;
    startPagePopUpMenu _selection = startPagePopUpMenu.logout;

    return FutureBuilder(
        future: connectToFirebase(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return SplashScreen();
          } else {
            return WillPopScope(
              onWillPop: () async {
                Test.shouldPop = 0;
                return false;
              },
              child: Scaffold(
                body: SafeArea(
                  top: true,
                  bottom: true,
                  child: SingleChildScrollView(
                    child: Padding(
                      padding: EdgeInsets.all(40),
                      child: Container(
                        height: screenHeight,
                        child: Column(
                          children: [
                            Container(
                              height: 30,
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  Text(
                                    "App Name",
                                    style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 20.0),
                                  ),
                                  PopupMenuButton<startPagePopUpMenu>(
                                    onSelected: (startPagePopUpMenu result) {
                                      setState(() {
                                        _selection = result;
                                      });
                                    },
                                    itemBuilder: (BuildContext context) =>
                                        <PopupMenuEntry<startPagePopUpMenu>>[
                                      PopupMenuItem<startPagePopUpMenu>(
                                        value: startPagePopUpMenu.logout,
                                        child: Row(
                                          children: <Widget>[
                                            Icon(Icons.exit_to_app_rounded),
                                            Text(" Logout")
                                          ],
                                        ),
                                      ),
                                    ],
                                  )
                                ],
                              ),
                            ),
                            SizedBox(
                              height: 30,
                            ),
                            Container(
                                height: screenHeight -
                                    91 -
                                    kBottomNavigationBarHeight,
                                child: StreamBuilder(
                                    stream: database.getData(),
                                    builder: (context, snapshotData) {
                                      // Here's a Widget, which opens Example Page 2
                                    })),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            );
          }
        });
}

示例第 2 页

这个页面是用一个小部件打开的

    Test.shouldPop = 1;

    double screenHeight = MediaQuery.of(context).size.height - 80;

    return FutureBuilder(
      future: connectToFirebase(),
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.waiting) {
          return Scaffold(
            body: SafeArea(
              top: true,
              bottom: true,
              child: SingleChildScrollView(
                child: Padding(
                  padding: EdgeInsets.all(40),
                  child: Container(
                    height: screenHeight,
                    child: Column(
                      children: [
                        Container(
                          height: 30,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: [
                              InkWell(
                                onTap: () {
                                  Test.shouldPop = 0;
                                  Navigator.pop(context);
                                },
                                child: Row(
                                  children: [
                                    Icon(Icons.arrow_back_ios_rounded),
                                    Text(
                                      "some stuff",
                                      style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          fontSize: 20.0),
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                        ),
                        SizedBox(
                          height: 30,
                        ),
                        Container(
                            height:
                                screenHeight - 91 - kBottomNavigationBarHeight,
                            child: StreamBuilder(
                                stream: database.getData(),
                                builder: (context, dataSnapshot) {
                                  
                                })),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
        } else {
          return SplashScreen();
        }
      },
    );

希望一切都有可能理解或丢失信息,否则请随时提问!感谢您的帮助和努力!

标签: androidflutterdartnavigationflutter-bottomnavigation

解决方案


推荐阅读