我想让外部页面上的底部导航菜单保持颤动

I want to keep the bottom navigation menu on external page in flutter

我实现了不同类型的菜单(底部导航栏、cupertino 和自定义导航栏),但没有解决问题。 我不想使用应用栏返回,只能使用菜单。 所以工作流程将是这样的:3 个按钮 - 提要、主页和个人资料。 在菜单的主页上,我将有一个按钮。当我按下那个按钮时,我想显示菜单,即使那一刻没有按钮处于活动状态。 cupertino 解决方案对我有用,但我遇到了问题。主页按钮处于活动状态,我无法返回主屏幕。

class Menu extends StatefulWidget {
  const Menu({Key? key}) : super(key: key);

  @override
  _MenuState createState() => _MenuState();
}

class _MenuState extends State<Menu> {
  int _currentIndex = 1;
  final List _children = [
    Feed(),
    Home(),
    Profile(),
  ];
  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(

      backgroundColor: Colors.transparent,
      tabBar: CupertinoTabBar(
        onTap: onTabTapped, // new
        currentIndex: _currentIndex,
        //type: BottomNavigationBarType.fixed, // Fixed
        backgroundColor: Colors.white, // <-- This works for fixed
        //unselectedItemColor: Color(0xff221F1E),
        //selectedItemColor: Color(0xffE4BDB6),
        //showSelectedLabels: false,
        //showUnselectedLabels: false,
        items: [
          BottomNavigationBarItem(
            icon: new Icon(Icons.chat_rounded, size: 28),
            label: 'Feed',
          ),
          BottomNavigationBarItem(
            icon: new Icon(Icons.home, size: 28),
            label: 'Home',
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.account_circle, size: 28),
              label: 'Profile'
          )
        ],
      ),
        tabBuilder: (BuildContext context, int index) {
          return CupertinoTabView(
            builder: (BuildContext context) {
              return SafeArea(
                top: false,
                bottom: false,
                child: CupertinoApp(
                  home: CupertinoPageScaffold(
                    resizeToAvoidBottomInset: false,
                    child: _children[_currentIndex],
                  ),
                ),
              );
            },
          );
        }
    );
  }
  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }


}

在首页小部件中-

onTap: () {
Navigator.of(context, rootNavigator: false).pushReplacement(MaterialPageRoute(
builder: (context) => VisionBoard(), maintainState: false));
}

我希望在从主页上单击该按钮后,可以通过单击它 return 回到主页 page/widget。现在,它似乎处于活动状态,没有任何反应。

有很多方法可以做到,但最简单的方法是这个包

persistent_bottom_nav_bar: ^4.0.2

您可以使用persistent_bottom_nav_bar来达到您的期望。操作如下:

 late PersistentTabController _controller;
 @override
void initState() {
    super.initState();
    _controller = PersistentTabController(initialIndex: 0);
   
  }
     List<PersistentBottomNavBarItem> _navBarsItems() {
    return [
      PersistentBottomNavBarItem(
        icon: Image.asset('assets/logowhite.png', height: 30, width: 30),
        inactiveIcon:
            Image.asset('assets/logowhite.png', height: 30, width: 30),
        title: "Vesvusa",
        textStyle: const TextStyle(color: Colors.white),
        activeColorPrimary: MyTheme.grey,
        activeColorSecondary: Colors.white,
        contentPadding: 5,
        inactiveColorPrimary: Colors.white,
        inactiveColorSecondary: Colors.white,
        routeAndNavigatorSettings: RouteAndNavigatorSettings(
          initialRoute: '/dashboard',
          routes: {
            '/newsevents': (context) => NewsListScreen(
                menuScreenContext: context,
                hideMainAppBar: hideMainAppBar,
                itemCount: null),
            '/blogdetails': (context) => BlogDetails(
                  menuScreenContext: context,
                  hideMainAppBar: hideMainAppBar,
                ),
            '/videoslist': (context) => VideosList(menuScreenContext: context),
            '/bookings': (context) => Bookings(menuScreenContext: context),
            '/lookstheme': (context) => LooksTheme(menuScreenContext: context),
            '/catalog': (context) => Catalog(menuScreenContext: context),
            '/productdetails': (context) =>
                ProductDetails(menuScreenContext: context),
          },
        ),
      ),
      PersistentBottomNavBarItem(
        icon: Image.asset(
          'assets/search.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        inactiveIcon: Image.asset(
          'assets/search.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        title: ("Search"),
        activeColorPrimary: MyTheme.grey,
        activeColorSecondary: Colors.white,
        contentPadding: 5,
        inactiveColorPrimary: Colors.white,
        inactiveColorSecondary: Colors.white,
        routeAndNavigatorSettings: const RouteAndNavigatorSettings(
          initialRoute: '/search',
          routes: {
//            '/first': (context) => MainScreen2(),
//            '/second': (context) => MainScreen3(),
          },
        ),
      ),
      PersistentBottomNavBarItem(
        icon: Image.asset(
          'assets/favourite.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        inactiveIcon: Image.asset(
          'assets/favourite.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        title: ("Favorite"),
        activeColorPrimary: MyTheme.grey,
        activeColorSecondary: Colors.white,
        contentPadding: 5,
        inactiveColorPrimary: Colors.white,
        inactiveColorSecondary: Colors.white,
        textStyle: const TextStyle(color: Colors.white),
        routeAndNavigatorSettings: const RouteAndNavigatorSettings(
          initialRoute: '/favorite',
          routes: {
//              '/first': (context) => MainScreen2(),
//              '/second': (context) => MainScreen3(),
          },
        ),
//          onPressed: (context) {
//            pushDynamicScreen(context,
//                screen: SampleModalScreen(), withNavBar: true);
//          }
      ),
      PersistentBottomNavBarItem(
        icon: Image.asset(
          'assets/cart.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        inactiveIcon: Image.asset(
          'assets/cart.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        title: ("Cart"),
        activeColorPrimary: MyTheme.grey,
        activeColorSecondary: Colors.white,
        contentPadding: 5,
        inactiveColorPrimary: Colors.white,
        inactiveColorSecondary: Colors.white,
        textStyle: const TextStyle(color: Colors.white),
        routeAndNavigatorSettings: const RouteAndNavigatorSettings(
          initialRoute: '/cart',
          routes: {
//            '/first': (context) => MainScreen2(),
//            '/second': (context) => MainScreen3(),
          },
        ),
      ),
      PersistentBottomNavBarItem(
        icon: Image.asset(
          'assets/profile.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        inactiveIcon: Image.asset(
          'assets/profile.png',
          height: 25,
          width: 25,
          color: Colors.white,
        ),
        title: ("Profile"),
        activeColorPrimary: MyTheme.grey,
        activeColorSecondary: Colors.white,
        contentPadding: 5,
        inactiveColorPrimary: Colors.white,
        inactiveColorSecondary: Colors.white,
        textStyle: const TextStyle(color: Colors.white),
        routeAndNavigatorSettings: RouteAndNavigatorSettings(
          initialRoute: '/profile',
          routes: {
            '/orders': (context) => MyOrders(
                  menuScreenContext: context,
                ),
            '/loginsecurity': (context) => LoginSecurity(
                  menuScreenContext: context,
                ),
            '/payment': (context) => Payment(
                  menuScreenContext: context,
                ),
            '/message': (context) => Messages(
                  menuScreenContext: context,
                ),
            '/devices': (context) => Devices(
                  menuScreenContext: context,
                ),
            '/devices': (context) => Devices(
                  menuScreenContext: context,
                ),
            '/inboxdetails': (context) => InboxDetails(
                  menuScreenContext: context,
                ),
            '/loyalty': (context) => Loyalty(menuScreenContext: context),
          },
        ),
      ),
    ];
  }

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: MyTheme.themeColor,
      appBar:  AppBar(
              elevation: 0,
              iconTheme: IconThemeData(
                color: MyTheme.grey,
              ),
              centerTitle: true,
              backgroundColor: MyTheme.themeColor,
              title: Image.asset("assets/titles.png", height: 60, width: 100),
              actions: [
                Builder(
                  builder: (context) {
                    return InkWell(
                        onTap: () {
                          Scaffold.of(context).openEndDrawer();
                        },
                        child: Padding(
                          padding: const EdgeInsets.fromLTRB(0, 0, 20, 0),
                          child: Icon(Icons.notifications_none_outlined,
                              color: MyTheme.grey),
                        ));
                  },
                )
              ],
            ),
      drawer: MyDrawer(),
      endDrawer: const NotificationDrawer(),
      body: PersistentTabView(
        context,
        controller: _controller,
        screens: _buildScreens(),
        items: _navBarsItems(),
        confineInSafeArea: true,
        backgroundColor: MyTheme.themeColor,
        handleAndroidBackButtonPress: true,
        resizeToAvoidBottomInset: true,
        stateManagement: true,

        hideNavigationBarWhenKeyboardShows: true,
        margin: const EdgeInsets.all(0.0),
        popActionScreens: PopActionScreensType.once,
        bottomScreenMargin: 0.0,
        onWillPop: (context) async {
          await showDialog(
              context: context!,
              useSafeArea: false,
              builder: (context) => CommonAlert());
          return false;
        },
        selectedTabScreenContext: (context) {
          context = context;
        },
        hideNavigationBar: _hideNavBar,

        popAllScreensOnTapOfSelectedTab: true,

        itemAnimationProperties: const ItemAnimationProperties(
          duration: Duration(milliseconds: 200),
          curve: Curves.ease,
        ),
        screenTransitionAnimation: const ScreenTransitionAnimation(
          animateTabTransition: true,
          curve: Curves.ease,
          duration: Duration(milliseconds: 200),
        ),
        navBarStyle:
            NavBarStyle.style7, // Choose the nav bar style with this property
      ),
    );
  }

您可以导航到其他页面执行此操作

 pushNewScreen(context,
                              screen: Loyalty(
                                menuScreenContext: context,
                              ),pageTransitionAnimation:PageTransitionAnimation.scale);
                        },

我在考虑 2 个选择:

  1. 使用普通的按钮导航栏,但不带导航改变页面,可以更新状态(我看到过类似的,但不推荐这种方式)
  2. 创建一个自定义导航栏(创建一个看起来像它的小部件),您可以将其用作 2 个页面的通用 UI 小部件(推荐)

希望我已经解决了问题。

使用persistent_bottom_nav_bar包。它为 Flutter 提供了 persistent/static 底部导航栏。