简体   繁体   English

如何在 flutter 中获取多个 ExpansionTile 的选定索引

[英]how get selected index of multiple ExpansionTile in flutter

how get selected index of multiple ExpansionTile in flutter?如何在 flutter 中获取多个 ExpansionTile 的选定索引? i need sidebar menu with multiple expansiontile and listtile.我需要带有多个 expansiontile 和 listtile 的侧边栏菜单。 how can i get selected index to change selected color menu with provider or bloc?我怎样才能获得选定的索引来更改与提供商或集团选定的颜色菜单

在此处输入图像描述

   children: [
              ExpansionTile(
                title: Text('main a'),
                children: [
                  ListTile(
                    title: Text('a1'),
                  ),
                  ListTile(
                    title: Text('a2'),
                  ),
                  ExpansionTile(
                    title: Text('a3'),
                    children: [
                      ListTile(
                        title: Text('a31'),
                      ),
                      ListTile(
                        title: Text('a32'),
                      ),
                      ListTile(
                        title: Text('a32'),
                      ),
                    ],
                  ),
                ],
              ),
              ExpansionTile(
                title: Text('main b'),
                children: [
                  ListTile(
                    title: Text('b1'),
                  ),
                  ListTile(
                    title: Text('b2'),
                  ),
                  ListTile(
                    title: Text('b3'),
                  ),
                ],
              ),
            ],

You can use onTap from ListTile , and create state variables to hold selected item.您可以使用ListTile中的onTap ,并创建状态变量来保存所选项目。 Like here I am using String.就像这里我使用的是字符串。 Based on your data, creating model class or map might be better choice.根据您的数据,创建模型类或地图可能是更好的选择。

  String? aValue;

  ....

  ExpansionTile(
            title: Text('main a'),
            children: [
              ListTile(
                title: Text('a1'),
                onTap: () {
                  aValue = "a1";
                  setState(() {});
                },
              ),     

This is a hassle to dynamically change the color of the ListTile() which have two different parent widget but with some extra code, you can do the same.动态更改ListTile()的颜色很麻烦,它有两个不同的父窗口小部件,但使用一些额外的代码,您可以执行相同的操作。


Full Code完整代码

// You can also use `Map` but for the sake of simplicity I'm using two separate `List`.
  final List<String> _parentlist1 = ["a1", "a2"];
  final List<String> _childOfParentlist1 = ["a31", "a32", "a34"];
  final List<bool> _isSelectedForParentList1 = List.generate(
      2,
      (i) =>
          false); // Fill it with false initially and this list for all the textList
  final List<bool> _isSelectedForChildOfParentList1 =
      List.generate(2, (i) => false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ExpansionTile(
        title: const Text('main a'),
        children: [
          ListView.builder(
            itemBuilder: (_, i) {
              return ListTile(
                tileColor: _isSelectedForParentList1[i]
                    ? Colors.blue
                    : null, // If current item is selected show blue color
                title: Text(_parentlist1[i]),
                onTap: () => setState(() => _isSelectedForParentList1[i] =
                    !_isSelectedForParentList1[i]), // Reverse bool value
              );
            },
          ),
          ExpansionTile(
            title: const Text('a3'),
            children: [
              ListView.builder(
                itemBuilder: (_, i) {
                  return ListTile(
                    tileColor: _isSelectedForChildOfParentList1[i]
                        ? Colors.blue
                        : null, // If current item is selected show blue color
                    title: Text(_childOfParentlist1[i]),
                    onTap: () => setState(() =>
                        _isSelectedForChildOfParentList1[i] =
                            !_isSelectedForChildOfParentList1[
                                i]), // Reverse bool value
                  );
                },
              ),
            ],
          ),
        ],
      ),
    );
  }

I hope this is helpful.我希望这是有帮助的。

You can use a ListView to contain the ExpansionTile widgets and a ListTile widgets.您可以使用 ListView 来包含 ExpansionTile 小部件和 ListTile 小部件。 Then you can use a currentIndex variable to keep track of the index of the currently selected menu item.然后您可以使用 currentIndex 变量来跟踪当前所选菜单项的索引。 You can use a Provider or BLoC to manage the currentIndex variable and to notify the widget tree when the value of currentIndex changes.您可以使用 Provider 或 BLoC 来管理 currentIndex 变量并在 currentIndex 的值更改时通知小部件树。

Here is the full code这是完整的代码

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => MenuModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ExpansionTile Demo'),
      ),
      body: MenuList(),
    );
  }
}

class MenuList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final model = Provider.of<MenuModel>(context);
    return ListView(
      children: <Widget>[
        ExpansionTile(
          title: Text('Menu 1'),
          children: <Widget>[
            ListTile(
              title: Text('Menu 1.1'),
              onTap: () {
                model.updateIndex(0);
              },
              selected: model.currentIndex == 0,
            ),
            ListTile(
              title: Text('Menu 1.2'),
              onTap: () {
                model.updateIndex(1);
              },
              selected: model.currentIndex == 1,
            ),
          ],
        ),
        ExpansionTile(
          title: Text('Menu 2'),
          children: <Widget>[
            ListTile(
              title: Text('Menu 2.1'),
              onTap: () {
                model.updateIndex(2);
              },
              selected: model.currentIndex == 2,
            ),
            ListTile(
              title: Text('Menu 2.2'),
              onTap: () {
                model.updateIndex(3);
              },
              selected: model.currentIndex == 3,
            ),
          ],
        ),
      ],
    );
  }
}

class MenuModel with ChangeNotifier {
  int _currentIndex = 0;

  int get currentIndex => _currentIndex;

  void updateIndex(int index) {
    _currentIndex = index;
    notifyListeners();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM