1

I implemented different types of menus (bottom navigation bar, cupertino and custom navigation bar), but I didn't solve the problem. I don't want to use the app bar to go back, only the menu. So the workflow will be like this: 3 buttons - feed, home and profile. On home page from the menu I will have a button. When I press that button, I want to display the menu even if no buttons are active in that moment. The cupertino solution worked for me, but I have a problem. The home button it's active and I can't go back to home screen.

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;
    });
  }


}

In the home widget -

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

I want after I click that button from Home page, to have the possibility to return to home page/widget by clicking on it. Now, it appears active and nothing happens.

Roland Iordache
  • 325
  • 4
  • 20
  • The description that you have written is kind of confusing, don't know what you are trying to achieve. So from what you have said i have written aanswer in different post, if that is what you are expecting check that one : https://stackoverflow.com/a/70589881/12000053 – Sagar Acharya Feb 08 '22 at 06:26
  • Hello. Sorry if the description is a little bit confusing. I read your answer and that's what I explained. Everything is working as in your example, but I don't want to have an app bar and a left arrow to go back, I just want to click again to home button from menu, and redirect to first page, pop up the second one. Do you understand? – Roland Iordache Feb 08 '22 at 13:01
  • so that is implemented in the demo itself, check the first tab which is home icon and press the move the new page and then press the home icon it will give you the desired output move to the first home page itself – Sagar Acharya Feb 08 '22 at 14:19
  • you can remove the appbar from the example – Sagar Acharya Feb 08 '22 at 14:20
  • Let me know if it works for you. – Sagar Acharya Feb 08 '22 at 14:20
  • I don't have time for today I will still update the code as per your requirement. – Sagar Acharya Feb 08 '22 at 14:23
  • If I press again the home icon, the output desired is the home page (after pop up the second page from home button), but nothing happens. Actually, that is the problem, that the home page remains active and can not go back to home page, when clicking on it, only with a back button from the app bar, which I do not want. – Roland Iordache Feb 08 '22 at 14:46
  • I have updated the code please take the pull from master. please check it now you can use a back button to remove all the pages from the stack for that specific botton bar item. – Sagar Acharya Feb 09 '22 at 05:51
  • I will check immediately, but the client doesn't want to use a back button, just the menu... – Roland Iordache Feb 14 '22 at 17:37
  • So you can do is I the latest push i have added the Widget WillPopScope you can remove every thing inside it and just return false in it so that you cannot make the backpress. – Sagar Acharya Feb 15 '22 at 04:28
  • Sorry, but it's hard to understand something from your repo. – Roland Iordache Feb 15 '22 at 17:38
  • Is it because the bloc architecture that i have used. – Sagar Acharya Feb 16 '22 at 05:23
  • You are trying to update a parent value from a child widget, so you need to use a better state management like Provider. I mean, you are trying to update _currentIndex from Home(), but Home doesn't know about _currentIndex. – Carlos Sandoval Feb 17 '22 at 08:32

4 Answers4

2

You can use persistent_bottom_nav_bar to achieve your expectation. Do as follows:

 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
      ),
    );
  }

You can navigate to other page doing this

 pushNewScreen(context,
                              screen: Loyalty(
                                menuScreenContext: context,
                              ),pageTransitionAnimation:PageTransitionAnimation.scale);
                        },
Nabin Dhakal
  • 1,949
  • 3
  • 20
  • 48
2

Use persistent_bottom_nav_bar package. It provides persistent/static bottom navigation bar for Flutter.

Jagal R Nath
  • 316
  • 5
  • 14
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 21 '22 at 14:33
1

there is a many ways to do it but the easiest one is this package

persistent_bottom_nav_bar: ^4.0.2
1

I'm thinking in 2 choices:

  1. using normal button navigation bar but not with the navigation to change the page, you can update the state (I saw something like that but it's not recommended way)
  2. create a custom navigation bar (create a Widgets that looks like it) and you can use it as a common UI widget at the 2 pages (recommended)

I hope that I have solved the problem.

Mohamed Reda
  • 1,207
  • 13
  • 21