1

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;
    });
  }
Tom
  • 13
  • 2

2 Answers2

0

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

Work
  • 46
  • 5
0

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.

Romil Mavani
  • 376
  • 6