skip to Main Content

I am currently developing a cross platform app in which I wanted to use a Sidebar for navigation on desktop and tablet view, but a bottom navigation bar for mobile, as it isn’t really handy to use a sidebar on mobile.
I have trouble with the navigation part, as for the sidebar I can just easily use the push() function. But with the bottomNavBar I have to use the onItemTapped function with indexes etc. Is there an easy way to use them together/switch between them?

This is my navigation for the Sidebar:

@override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => page),
        );
      },

And this is how I tried to do the bottomNavBar navigation:

currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
      body: PageNavigationItem.items.elementAt(_selectedIndex),
    );
  } // build method

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

2

Answers


  1. There is, to my knowledge, no way to solve your issue unless you "make your own bottom navigation bar".

    I would however ask if you don’t want to use a Drawer widget instead of a bottom navigation bar as it is a way to keep your app consistent across platforms, follows flutters guidelines for projects and permit you to use push. It is a "sidebar" in a sense.

    I would do my own bottom navigation bar if I felt I needed it no matter what,something like this:

    import 'package:flutter/material.dart';
    
    class BottomNavigationBarWidget extends StatelessWidget {
      final List<Widget> children;
      final Widget body;
      const BottomNavigationBarWidget({Key? key, required this.children, required this.body}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Expanded(child: body),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: children,
            )
          ],
        );
      }
    }
    

    with this in the main page
    class MyHomePage extends StatelessWidget {
    const MyHomePage({Key? key}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Flutter app'),
          ),
          body: BottomNavigationBarWidget(
            body: Center(
              child: Text('Hello world!'),
            ),
            children: [
              Column(children:[Icon(Icons.percent), Text("Test")])
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              print('Zapp!');
            },
            backgroundColor: Colors.yellow[700],
            child: Icon(
              Icons.bolt,
              color: Colors.black,
            ),
          ),
        );
      }
    }
    

    This is the result

    enter image description here

    But seriously, it is just easier and better to use a Drawer widget

    Login or Signup to reply.
  2. Yes it is possible and once check below example code.

    Video of how it will works.
    https://drive.google.com/file/d/1BxK6qevJOu4qYrmnoTXdIYtqLAVC87ya/view?usp=share_link

    Here we are creating a model for Title and onTap

    class DataModel {
      final String labelName;
      final Function onTap;
      const DataModel({required this.labelName, required this.onTap});
    }
    

    Here we are creating a list of DataModel so will use in Title and onTap.

    List<DataModel> dataList = [
        DataModel(
            labelName: "First",
            onTap: () {
              print("first");
            }),
        DataModel(
            labelName: "Second",
            onTap: () {
              print("Second");
            }),
        DataModel(
            labelName: "Third",
            onTap: () {
              print("Third");
            }),
        DataModel(
            labelName: "Fourth",
            onTap: () {
              print("Fourth");
            }),
      ];
    

    Function for get device is mobile or tablet

    getDevice() {
        return MediaQuery.of(context).size.width <= 800 ? "Mobile" : "Tablet";
      }
    

    here is full code of that page.

    class MyHomePage extends StatefulWidget {
      const MyHomePage({
        super.key,
      });
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Demo Home Page"),
          ),
          drawer: getDevice() == "Tablet"
              ? Drawer(
                  child: ListView.builder(
                  itemCount: dataList.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(dataList[index].labelName),
                      onTap: () {
                        dataList[index].onTap();
                      },
                    );
                  },
                ))
              : null,
          bottomNavigationBar: getDevice() == "Mobile"
              ? BottomNavigationBar(
                  onTap: (value) {
                    dataList[value].onTap();
                  },
                  // backgroundColor: Colors.black,
                  items: dataList.map((e) => BottomNavigationBarItem(backgroundColor: Colors.black, icon: Icon(Icons.add), label: e.labelName)).toList(),
                  // items: <BottomNavigationBarItem>[
                  //   BottomNavigationBarItem(label: "Test", icon: Icon(Icons.add)),
                  //   BottomNavigationBarItem(label: "Test1", icon: Icon(Icons.add)),
                  //   BottomNavigationBarItem(label: "Test2", icon: Icon(Icons.add)),
                  //   BottomNavigationBarItem(label: "Test3", icon: Icon(Icons.add)),
                  // ],
                )
              : null,
          body: Center(
            child: TextButton(
                onPressed: () {
                  setState(() {
                    // isHide = !isHide;
                  });
                },
                child: Text("Hide")),
          ),
        );
      }
    

    I Hope these things are solve your issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search