theowl-0011
theowl-0011

Reputation: 63

Flutter: Persistent BottomAppBar and BottomNavigationBar

I am new to flutter, and I am building an app that has BottomAppBar which takes the property bottomNavigationBar: of Scaffold() for my home_screen, because I needed it to be at the bottom of the screen and persistent throughout the pages, and I also need a BottomNavigationBar to be persistent also at the top of BottomAppBar, but I can't make that happen because BottomAppBar already takes the bottomNavigationBar: property.

How can I make my BottomNavigationBar persistent alongside my BottomAppBar?

Note: I am using PageView() to scroll through my pages and it will be controlled by the BottomNavigationBar

Edit: attached here is the UI that I am trying to achieve persistent BottomNavigationBar at the top of BottomAppBar

code snippet:

import 'package:flutter/material.dart';

//screens
import 'package:timewise_flutter/screens/calendar_screen.dart';
import 'package:timewise_flutter/screens/covey_quadrants_screen.dart';
import 'package:timewise_flutter/screens/kanban_screen.dart';
import 'package:timewise_flutter/screens/todo_list_screen.dart';

class OverviewScreen extends StatefulWidget {
  static const String id = 'overview_screen';

  //const OverviewScreen({Key? key}) : super(key: key);

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

class _OverviewScreenState extends State<OverviewScreen> {
  PageController _pageController = PageController(initialPage: 2);
  int _bottomNavBarCurrentIndex = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      bottomNavigationBar: SafeArea(
        child: BottomAppBar(
          elevation: 16.0,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              IconButton(
                tooltip: 'Menu',
                icon: Icon(Icons.menu_rounded),
                onPressed: () {
                  print('menu icon pressed!');
                  //TODO: show bottom modal bottom sheet
                },
              ),
              IconButton(
                tooltip: 'Pomodoro Timer',
                icon: Icon(Icons.hourglass_empty_rounded),
                onPressed: () {
                  print('pomo icon pressed!');
                  //TODO: show pomodoro timer modal bottom sheet
                },
              ),
              IconButton(
                tooltip: 'Add',
                icon: Icon(Icons.add_circle_outline_outlined),
                onPressed: () {
                  print('add icon pressed!');
                  //TODO: show add task modal bottom sheet
                },
              ),
            ],
          ),
        );,
      ),
      body: PageView(
        controller: _pageController,
        onPageChanged: (page) {
          setState(() {
            _bottomNavBarCurrentIndex = page;
          });
        },
        children: [
          CalendarScreen(),
          ToDoListScreen(),
          SafeArea(
            child: Container(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text('Overview Screen'),
                  BottomNavigationBar(
                    currentIndex: _bottomNavBarCurrentIndex,
                    type: BottomNavigationBarType.fixed,
                    backgroundColor: Colors.white,
                    elevation: 0.0,
                    iconSize: 16.0,
                    selectedItemColor: Colors.black,
                    unselectedItemColor: Colors.grey,
                    showSelectedLabels: false,
                    showUnselectedLabels: false,
                    items: [
                      BottomNavigationBarItem(
                        icon: Icon(Icons.calendar_today_rounded),
                        label: 'Calendar',
                        tooltip: 'Calendar',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.checklist_rounded),
                        label: 'To-Do',
                        tooltip: 'To-Do List',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.panorama_fish_eye_rounded),
                        label: 'Overview',
                        tooltip: 'Overview',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.border_all_rounded),
                        label: 'Covey\'s 4 Quadrants',
                        tooltip: 'Covey\'s 4 Quadrants',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.view_column_rounded),
                        label: 'Kanban Board',
                        tooltip: 'Kanban Board',
                      ),
                    ],
                    onTap: (index) {
                      setState(() {
                        _bottomNavBarCurrentIndex = index;
                        _pageController.jumpToPage(index);
                      });
                    },
                  ),
                ],
              ),
            ),
          ),
          CoveyQuadrantsScreen(),
          KanbanScreen(),
        ],
      ),
    );
  }
}

Upvotes: 0

Views: 1309

Answers (2)

Swaminathan V
Swaminathan V

Reputation: 4781

Unfortunately, this is not a standard way in which the mobile app UI should be designed. This will result in bad user experience.

What if user accidently touches on NavigationBar instead of AppBar. You will be taken to the new screen and action that I performed there will be lost or need to handle.

So proper UI guidelines should be met, while we design and develop for the mobile app. Based on guidelines from material.io

Bottom app bars should be used for:

  • Mobile devices only
  • Access to a bottom navigation drawer
  • Screens with two to five actions

Bottom app bars shouldn't be used for:

  • Apps with a bottom navigation bar
  • Screens with one or no actions

Refer this link for more useful information about the UI and UX guidelines https://material.io/

Upvotes: 2

RaviPenikelapati
RaviPenikelapati

Reputation: 11

I would suggest making a scaffold() with the bottomNavigationBar() as you did. Then you could create a list of Container() objects each representing a different page. For your PageView I'm assuming you have done that, if not then that's the way to do it. Then you could cycle through your pages by setting the body: property of the scaffold to myPages[_currentIndex] or something like that.

Additionally: Like the comment asks, I am also not sure why you would want both BottomNavigationBar and BottomAppBar they both do exactly the same thing. In either case the process is the same as what I described above.

Upvotes: 0

Related Questions