How to remember and highlight selected drawer items using ListTile?

Viewed 1756

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,
      ),
  );
}
1 Answers

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),
      ),
    );
  }
}
Related