I successfully achieve the sidebar menu by using drawer and ListTile, but the problem is when the ListTile tapped and the drawer closed, I reopen the drawer will see that the tapped ListTile will be reset to untapped color. How to solve this problem? I try so many time but I can’t figure the solution out.
menu_list dart file
class MenuList extends StatefulWidget {
final Function(int, String) onTap;
List<Map<String, dynamic>> menu = [];
MenuList({required this.onTap, required this.menu});
@override
State<MenuList> createState() => _MenuListState();
}
class _MenuListState extends State<MenuList> {
int _selectedIndex = 0;
Widget buildListTile(Map<String, dynamic> item, int index) {
return ListTile(
title: Text(
item["title"],
style: TextStyle(
color: _selectedIndex == index ? Colors.deepOrangeAccent : Colors.grey,
),
),
leading: Icon(
item['leading'],
color: _selectedIndex == index ? Colors.deepOrangeAccent : Colors.grey,
),
tileColor: Colors.white,
onTap: (){
setState(() {
_selectedIndex = index;
});
widget.onTap(index, item['title']);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: widget.menu.length,
itemBuilder: (BuildContext context, int index) {
return buildListTile(widget.menu[index], index);
},
),
);
}
}
mDashboard dart file
class MobileDashboard extends StatefulWidget {
@override
State<MobileDashboard> createState() => _MobileDashboardState();
}
class _MobileDashboardState extends State<MobileDashboard> {
final _auth = FirebaseAuth.instance;
final PageController _pageController = PageController(initialPage: 0);
String _selectedTitle = '';
final List<Map<String, dynamic>> menu = [
{'title': 'Playlists', 'leading':Icons.featured_play_list},
{'title': 'Menu..', 'leading':Icons.send},
{'title': 'Logout', 'leading':Icons.logout},
];
void handleTap(int index, String title) {
setState(() {
_selectedTitle = title;
});
}
@override
void initState() {
_selectedTitle = 'Playlists';
super.initState();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
endDrawer: Drawer(
child: ListView(
children: [
SizedBox(
height: 100,
child: DrawerHeader(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: IconButton(
onPressed: (){
Get.back(result: false);
},
icon: Icon(CupertinoIcons.xmark)
),
),
),
Icon(Icons.info_outline, size: 24, color: Colors.grey,),
SizedBox(width: 27.3,),
SizedBox(
width: 28,
height: 28,
child: CircleAvatar(backgroundImage: AssetImage('assets/loginBG.png'),),
),
],
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: MenuList(
onTap: handleTap,
menu: menu),
)
]
)
),
2
Answers
You can pass the initial index on
MenuList
.And on usecase(on state class)
inside build method
See the problem is, when you click on other item in your menu , it goes to other page lets say menu, Now again again page gets build and then MenuList() is called, inside MenuList() you have written int selectedindex = 0, so always it will display playlist. approach is also not a good one
Better approach is
Make a List of pages/Widgets you want to show like
static final List_widgetOptions = [
const Text("Home"),
UserProfilePage(),
const Text("Search"),
const Text("Settings")
];
then write drawer code when user taps on item it would get routed to widget we define in above list
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: [
code is different but understand the flow, we need to call pages from the drawer itself, and not like, from a page call a drawer