Nur Haslina
Nur Haslina

Reputation: 203

Is it possible to make the navigation drawer always open in Flutter?

I want the drawer to always open in screen so the user do not have to slide the screen from left to right. I found many question regarding this issue but I could not find it in Dart/Flutter.

This is the solution from @aziza on how to change the content of the Scaffold. body content upon user click on the Drawer but I want it to always open.

Flutter Drawer Widget - change Scaffold.body content

Flutter Drawer Widget - change Scaffold.body content

Upvotes: 11

Views: 24351

Answers (5)

Bawantha
Bawantha

Reputation: 4018

You need to create StateFullShellRoute with using go_router package

Upvotes: -1

ccpizza
ccpizza

Reputation: 31686

Instead of a Drawer you might want to consider the OOTB NavigationRail

As per the official documentation you can create a local sample project with

flutter create --sample=material.NavigationRail.1 mysample

Customized code and Live demo which shows the rail expanded by default:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'NavigationRail',
      home: const MyHomePage(title: 'NavigationRail'),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  bool extended =false;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Row(
        children: <Widget>[
          IntrinsicWidth(
            child: NavigationRail(
              elevation: 3,
              extended: true,

              selectedIndex: _selectedIndex,
              onDestinationSelected: (int index) {
                setState(() {
                  print(index);
                  _onItemTapped(index);
                  // _selectedIndex = index;
                });
              },
              labelType: NavigationRailLabelType.none,
              destinations: const <NavigationRailDestination>[

                NavigationRailDestination(
                  icon: Icon(Icons.bookmark_border),
                  selectedIcon: Icon(Icons.book),
                  label: Text('Accented'),
                ),
                NavigationRailDestination(
                  icon: Icon(Icons.star_border),
                  selectedIcon: Icon(Icons.star),
                  label: Text('Starred'),
                ),
              ],
            ),
          ),

          const VerticalDivider(thickness: 0, width: 0),
          Expanded(
            child: Center(
              child: Text("selected: $_selectedIndex" ),
            ),
          )
        ],
      ),
    );
  }
}

Moreover, the NavigationRail can be used as a Drawer's child, so you could for example use something like adaptive_breakpoints to detect the user's screen size and display a regular drawer in mobile viewports and the wide split view with the same navigationRail instance on desktop viewports.

Upvotes: 2

Pankaj Patil
Pankaj Patil

Reputation: 21

I have done this using scaffold drawer. Please see and try this

class _Dashbord extends State<Dashbord> {
  Widget bodyWidget = DashboardInitialContent();

  @override
  Widget build(BuildContext context) {
    final bool displayMobileLayout = MediaQuery.of(context).size.width < 500;
    return Row(
      children: [
        if (!displayMobileLayout)
          Drawer(
            // Add a ListView to the drawer. This ensures the user can scroll
            // through the options in the drawer if there isn't enough vertical
            // space to fit everything.
            child: ListView(
              // Important: Remove any padding from the ListView.
              // padding: EdgeInsets.zero,
              children: [
                DrawerHeader(
                  // decoration: const BoxDecoration(
                  //   color: Colors.white,
                  // ),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      SizedBox(
                        child: Image.asset(
                            "assets/images/3c98d8a48cfed2f87f377ec2b30130b4b9195af4.png"),
                      ),
                    ],
                  ),
                ),
                ListTile(
                  hoverColor: Colors.grey,
                  leading: const Icon(
                    Icons.dashboard,
                    color: Colors.deepOrange,
                  ),
                  title: const Text(
                    'Dashboard',
                    style: TextStyle(
                      fontSize: 20.0,
                      fontWeight: FontWeight.w600,
                      color: Colors.deepOrange,
                    ),
                  ),
                  onTap: () {
                    // Update the state of the app
                    // ...
                    // Then close the drawer
                    setState(() {
                      bodyWidget = DashboardInitialContent();
                    });
                  },
                )
              ],
            ),
          ),
        Expanded(
          child: Scaffold(
            appBar: AppBar(
              automaticallyImplyLeading: displayMobileLayout ? true : false,
              backgroundColor: Colors.deepOrange,
              actions: [
                IconButton(
                  icon: const Icon(Icons.notification_important_rounded),
                  tooltip: 'Notification',
                  onPressed: () {
                    ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(content: Text('This is a snackbar')));
                  },
                ),
                PopupMenuButton(
                  icon: const Icon(Icons.person_rounded),
                  tooltip: 'Profile',
                  itemBuilder: (BuildContext context) => <PopupMenuEntry>[
                    PopupMenuItem(
                      child: ListTile(
                        leading: Icon(Icons.edit),
                        title: Text('Edit Profile'),
                        onTap: () {
                          setState(() {
                            bodyWidget = UserProfile();
                            Navigator.pop(context);
                          });
                        },
                      ),
                    ),
                    PopupMenuItem(
                      child: ListTile(
                        leading: Icon(Icons.lock),
                        title: Text('Change Password'),
                        onTap: () {
                          setState(() {
                            bodyWidget = ChangePassword();
                            Navigator.pop(context);
                          });
                        },
                      ),
                    ),
                    const PopupMenuItem(
                      child: ListTile(
                        leading: Icon(Icons.logout),
                        title: Text('Sign out'),
                      ),
                    ),
                  ],
                ),
              ],
            ),
            drawer: displayMobileLayout
                ? Drawer(
                    // Add a ListView to the drawer. This ensures the user can scroll
                    // through the options in the drawer if there isn't enough vertical
                    // space to fit everything.
                    child: ListView(
                      // Important: Remove any padding from the ListView.
                      // padding: EdgeInsets.zero,
                      children: [
                        DrawerHeader(
                          // decoration: const BoxDecoration(
                          //   color: Colors.white,
                          // ),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              SizedBox(
                                child: Image.asset(
                                    "assets/images/3c98d8a48cfed2f87f377ec2b30130b4b9195af4.png"),
                              ),
                            ],
                          ),
                        ),
                        ListTile(
                          hoverColor: Colors.grey,
                          leading: const Icon(
                            Icons.dashboard,
                            color: Colors.deepOrange,
                          ),
                          title: const Text(
                            'Dashboard',
                            style: TextStyle(
                              fontSize: 20.0,
                              fontWeight: FontWeight.w600,
                              color: Colors.deepOrange,
                            ),
                          ),
                          onTap: () {
                            // Update the state of the app
                            // ...
                            // Then close the drawer
                            setState(() {
                              bodyWidget = DashboardInitialContent();
                            });
                            Navigator.pop(context);
                          },
                        )
                      ],
                    ),
                  )
                : null,
            body: bodyWidget,
          ),
        )
      ],
    );
  }
}

Upvotes: 1

jksevend
jksevend

Reputation: 458

I think my package suits your needs. I designed this originally for a desktop flutter app but decided to.make a package out of it.

https://pub.dev/packages/side_navigation

In the README you can also find an example and some pictures to showcase.

Cheers!

Upvotes: 3

ejabu
ejabu

Reputation: 3147

You may try this :

import 'package:flutter/material.dart';

class SideMenuScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Screen'),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: Row(
              mainAxisSize: MainAxisSize.max,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                Flexible(
                  child: ListView(
                    children: <Widget>[
                      ListTile(title: Text("Menu A")),
                      ListTile(title: Text("Menu B")),
                      ListTile(title: Text("Menu C")),
                      ListTile(title: Text("Menu D")),
                      ListTile(title: Text("Menu E")),
                      ListTile(title: Text("Menu F")),
                      ListTile(title: Text("Menu G")),
                      ListTile(title: Text("Menu H")),
                      ListTile(title: Text("Menu I")),
                      ListTile(title: Text("Menu J")),
                      ListTile(title: Text("Menu K")),
                      ListTile(title: Text("Menu L")),
                      ListTile(title: Text("Menu M")),
                    ],
                  ),
                ),
                Expanded(
                  child: Container(
                    child: Center(child: Text('Content')),
                    color: Colors.black26,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Demo

We can improve to more be interactive by PageView : Github Repo

Flexible(
  child: StaticDrawer(),
),
Expanded(
  child: PageView(
    children: <Widget>[
      MainContent(),
      MainContent(),
      MainContent(),
    ],
  ),
),

later you will find this ..

enter image description here

Upvotes: 13

Related Questions