How to remember and highlight selected drawer items using ListTile?

1,448

You can copy paste run full code below
You can use selectedIndex to control
In isSelected pass selectedIndex == 0 or selectedIndex == 1 ..etc
code snippet

int selectedIndex = 0;
...
_createDrawerItem(
                icon: Icons.timer,
                text: 'Timer',
                isSelected: selectedIndex == 0,
                onTap: () {
                  setState(() {
                    selectedIndex = 0;
                  });

                  Navigator.pushReplacementNamed(context, "/page0");
                }),

working demo

enter image description here

full code

import 'package:flutter/material.dart';

class NavDraw extends StatefulWidget {
  @override
  _NavDrawState createState() => _NavDrawState();
}

int selectedIndex = 0;

class _NavDrawState extends State<NavDraw> {

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: Container(
        child: ListView(
          children: <Widget>[
            Container(
              height: 100.0,
              color: Color(0xff2B4DB9),
              child: DrawerHeader(
                  margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
                  padding: EdgeInsets.zero,
                  decoration: BoxDecoration(
                      image: DecorationImage(
                          fit: BoxFit.none,
                          image: NetworkImage(
                              'https://picsum.photos/250?image=9')))),
            ),
            _createDrawerItem(
                icon: Icons.timer,
                text: 'Timer',
                isSelected: selectedIndex == 0,
                onTap: () {
                  setState(() {
                    selectedIndex = 0;
                  });

                  Navigator.pushReplacementNamed(context, "/page0");
                }),
            _createDrawerItem(
                icon: Icons.history,
                text: 'History',
                isSelected: selectedIndex == 1,
                onTap: () {
                  setState(() {
                    selectedIndex = 1;
                  });

                  Navigator.pushReplacementNamed(context, "/page1");
                }),
            _createDrawerItem(
                icon: Icons.help,
                text: 'Help & Support',
                isSelected: selectedIndex == 2,
                onTap: () {
                  setState(() {
                    selectedIndex = 2;
                  });

                  Navigator.pushReplacementNamed(context, "/page2");
                }),
            _createDrawerItem(
                icon: Icons.rate_review,
                text: 'Write a Review',
                isSelected: selectedIndex == 3,
                onTap: () {
                  setState(() {
                    selectedIndex = 3;
                  });

                  Navigator.pushReplacementNamed(context, "/page3");
                }),
            Divider(),
          ],
        ),
      ),
    );
  }
}

Widget _createDrawerItem(
    {IconData icon, String text, GestureTapCallback onTap, bool isSelected}) {
  return Ink(
    color: isSelected ? Color(0xffE3EAFF) : Colors.transparent,
    child: ListTile(
      selected: true,
      hoverColor: Colors.white,
      title: Row(
        children: <Widget>[
          Icon(icon),
          Padding(
            padding: EdgeInsets.only(left: 8.0),
            child: Text(text),
          )
        ],
      ),
      onTap: onTap,
    ),
  );
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      initialRoute: '/page0',
      routes: {
        '/page0': (context) => Page0(),
        '/page1': (context) => Page1(),
        '/page2': (context) => Page2(),
        '/page3': (context) => Page3(),
      },
    );
  }
}

class Page0 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        drawer: NavDraw(),
        appBar: AppBar(
          title: Text("page 0"),
        ),
        body: Text("page 0"));
    ;
  }
}

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        drawer: NavDraw(),
        appBar: AppBar(
          title: Text("page 1"),
        ),
        body: Text("page 1"));
    ;
  }
}

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        drawer: NavDraw(),
        appBar: AppBar(
          title: Text("page 2"),
        ),
        body: Text("page 2"));
    ;
  }
}

class Page3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        drawer: NavDraw(),
        appBar: AppBar(
          title: Text("page 3"),
        ),
        body: Text("page 3"));
    ;
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      drawer: NavDraw(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
Share:
1,448
Ned Bayne-Powell
Author by

Ned Bayne-Powell

Updated on December 22, 2022

Comments

  • Ned Bayne-Powell
    Ned Bayne-Powell over 1 year

    I'm using ListTile to display items on a navigation drawer but I'm having a hard time creating the isSelected Color and have applied it to the onTap using this but keep getting errors about the index and the app can't recognise the isSelected bool on the onTap:

      for(int i = 0; i < isSelected.length; i++){
                        setState(() {
                           if (index == i) {
                              isSelected[index] = true;
                           } else {                               //the condition to change the highlighted item
                              isSelected[i] = false;
                           }
                         });
    

    Here is the Navigation Drawer in Flutter that I have created, if you could give advice about how to take the 'isSelected' in the _createDrawerItem Widget and apply it to the drawer. I have already set 'isSelected' too true and false to the drawer items but can't seem to apply it to the onTap.

    class NavDraw extends StatefulWidget {
      @override
      _NavDrawState createState() => _NavDrawState();
    
    }
    
    class _NavDrawState extends State<NavDraw> {
    
      @override
      void initState() {
    
        super.initState();
    
      }
    
      Widget build(BuildContext context) {
        return Drawer(
          child: Container(
            child: ListView(
              children: <Widget> [
              Container(
                  height: 100.0,
                  color: Color(0xff2B4DB9),
                  child: DrawerHeader(
                      margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
                      padding: EdgeInsets.zero,
                      decoration: BoxDecoration(
                          image: DecorationImage(
                              fit: BoxFit.none,
                              image:  AssetImage('images/drawer_header.png')))),
                ),
              _createDrawerItem(
            icon: Icons.timer,
        text: 'Timer',
          isSelected: true,
          onTap: () =>
          Navigator.pushReplacementNamed(context, Routes.home)),
            _createDrawerItem(
            icon: Icons.history,
            text: 'History',
                isSelected: false,
                onTap: () =>
                Navigator.pushReplacementNamed(context, Routes.history)),
          _createDrawerItem(
            icon: Icons.help,
            text: 'Help & Support',
              isSelected: false,
              onTap: () =>
                Navigator.pushReplacementNamed(context, Routes.help_and_support)),
          _createDrawerItem(
            icon: Icons.rate_review,
            text: 'Write a Review',
              isSelected: false,
              onTap: () =>
                Navigator.pushReplacementNamed(context, Routes.write_a_review)),
          Divider(),
        ],
        ),
          ),
        );
      }
    }
    
    
    Widget _createDrawerItem(
    {IconData icon, String text, GestureTapCallback onTap, bool isSelected}) {
      return Ink(
        color: isSelected ? Color(0xffE3EAFF) : Colors.transparent,
        child: ListTile(
          selected: true,
          hoverColor: Colors.white,
          title: Row(
          children: <Widget>[
          Icon(icon),
          Padding(
          padding: EdgeInsets.only(left: 8.0),
          child: Text(text),
          )
          ],
          ),
          onTap: onTap,
          ),
      );
    }
    
  • Karan Alangat
    Karan Alangat over 3 years
    Thanks. Declaring variable outside the Class scope did the trick :)
  • Arijeet
    Arijeet almost 3 years
    How can i change the selectedIndex to 0 when the context gets popped off ?