dart 使用抽屉合并自建列表平铺菜单

gr8qqesn  于 2023-05-11  发布在  其他
关注(0)|答案(2)|浏览(150)

我通过使用drawer和ListTile成功地实现了侧边栏菜单,但问题是当ListTile点击并关闭drawer时,我重新打开drawer会看到点击的ListTile将重置为未点击的颜色。如何解决这一问题?我试了很多次,但我找不到解决办法。
菜单列表箭头文件

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文件

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),
                )
              ]
          )
      ),
7ivaypg9

7ivaypg91#

您可以在MenuList上传递初始索引。

class MenuList extends StatefulWidget {
  const MenuList({
    this.initialSelectedIndex = 0,
    required this.onTap,
    required this.menu,
  });
  final Function(int, String) onTap;
  final List<Map<String, dynamic>> menu;
  final int initialSelectedIndex;

  @override
  State<MenuList> createState() => _MenuListState();
}

class _MenuListState extends State<MenuList> {
  late int _selectedIndex = widget.initialSelectedIndex;

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

在用例上(在状态类上)

int selectedIndex = 0;

  void handleTap(int index, String title) {
    selectedIndex = index;
    setState(() {
      _selectedTitle = title;
    });
    .....code...
  }

内建方法

MenuList(
  onTap: handleTap,
  menu: menu,
  initialSelectedIndex: selectedIndex,
),
nhjlsmyf

nhjlsmyf2#

看到的问题是,当你点击菜单中的其他项目,它会转到其他页面,让我们说菜单,现在再次页面得到构建,然后MenuList()被调用,在MenuList()中你已经写了int selectedindex = 0,所以它总是会显示播放列表。方法也不是一个好方法
更好的方法是
1.制作一个你想要展示的页面/小部件列表
static final List_widgetOptions = [ const Text(“Home”),UserProfilePage(),const Text(“Search”),const Text(“Settings”)];

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

1.然后写抽屉代码时,用户点击项目,它会得到路由到小部件,我们在上面的列表中定义
@override Widget build(BuildContext context){ return Drawer(child:ListView(子项:[

UserAccountsDrawerHeader(

          accountName: GestureDetector(
          // onTap: () => setState(() {
          //     _selectedIndex = 1;
          //   }),
          onTap: () {
            setState(() {
              _selectedIndex = 1;
            });
            Navigator.pop(context);
          },
          child:const Text("username",style: TextStyle(fontSize: 20) ,)), 
        currentAccountPicture: CircleAvatar(
          child:  ClipOval(
            child: Image.asset('lib/images/dhruv.png.jpg',
            width:90,
            height : 90,
            fit :BoxFit.cover),


            )

        ),

        accountEmail:const Text("email")),
        ListTile(
          leading: Icon(Icons.payment),
          title: const Text("Home"),
           onTap: () {
             Navigator.pop(context);
            setState(() {
              _selectedIndex = 0;
            });
            Navigator.pop(context);

          },
        ),

代码是不同的,但理解流程,我们需要调用页从抽屉本身,而不是像,从一个页面调用一个抽屉

相关问题