如何在 ExpansionTile 中获取 ListTile 索引?

How do I get the ListTile index in an ExpansionTile?

展开列表然后单击子项后,我希望被单击的行更改颜色。此时index all time为0,导致所有subitem都高亮显示。如何获得正确的索引以便仅突出显示被点击的行?

当前状态:

Image

车辆class:

class Vehicle {
  final String title;
  List<String> contents = [];
  final IconData icon;

  Vehicle(this.title, this.contents, this.icon);
}

对象列表:

List<Vehicle> vehicles = [
  Vehicle(
    'Bike',
    ['Vehicle no. 1', 'Vehicle no. 2', 'Vehicle no. 7', 'Vehicle no. 10'],
    Icons.motorcycle,
  ),
  Vehicle(
    'Cars',
    ['Vehicle no. 3', 'Vehicle no. 4', 'Vehicle no. 6'],
    Icons.directions_car,
  ),
];

小部件:

class CreateNewViewPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _CreateNewViewPage();
}

class _CreateNewViewPage extends State<CreateNewViewPage> {
  int _selectedIndex;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      backgroundColor: const Color(0xFF000624),
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.transparent,
        title: Text(
          'Example',
          style: TextStyle(color: Colors.white),
        ),
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
      body: Column(
        children: <Widget>[
          Divider(
            color: Colors.white,
          ),
          Expanded(
            child: Container(
              width: MediaQuery.of(context).size.width / 1.4,
              child: ListView.builder(
                itemCount: 2,
                itemBuilder: (context, index) {
                  return Card(
                    child: ExpansionTile(
                      title: Text(vehicles[index].title, style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic),),
                      children: <Widget>[
                        Column(
                          children: _buildExpandableContent(vehicles[index], index),
                        ),
                      ],
                    ),
                  );
                },
              ),
            ),
          )
        ],
      ),
    );
  }

  _buildExpandableContent(Vehicle vehicle, index) {
    List<Widget> columnContent = [];

    for (String content in vehicle.contents)
      columnContent.add(
        ListTile(
          title: Text(content, style: new TextStyle(fontSize: 18.0),),
          leading: Icon(vehicle.icon),
          tileColor: _selectedIndex == index ? Colors.blue : null,
          onTap: () {
            setState(() {
              _selectedIndex = index;
            });
          },
        ),
      );

    return columnContent;
  }
}

更新您的 _buildExpandableContent 方法,如下面的代码所示:

 List<Widget> _buildExpandableContent(Vehicle vehicle, index) {
        return List.generate(vehicle.contents.length, (index) {
          return ListTile(
            title: Text(
              vehicle.contents[index],
              style: new TextStyle(fontSize: 18.0),
            ),
            leading: Icon(vehicle.icon),
            tileColor: _selectedIndex == index ? Colors.blue : null,
            onTap: () {
              setState(() {
                print('Selected Index : $index');// printing selected value to console
                _selectedIndex = index;
              });
            },
          );
        });
      }

控制台输出:

I/flutter ( 9502): Selected Index : 0
I/flutter ( 9502): Selected Index : 1
I/flutter ( 9502): Selected Index : 2
I/flutter ( 9502): Selected Index : 3
I/flutter ( 9502): Selected Index : 0
I/flutter ( 9502): Selected Index : 1
I/flutter ( 9502): Selected Index : 2

UI 输出:

现在,当 ExpansionTile 中的 ListTile 被点击时,您将获得正确的索引。

基于对其子项使用 ExpansionTile 索引也发生了问题:

您正在通过列表视图构建器生成 ExpansionTile 并将索引传递给 _buildExpandableContent 方法。因此,索引对于 ExpansionTile 的所有子项都是相同的。因此,ExpansionTile 中选择的所有子项。您需要从 vehicle.contents 中获取索引。我已经用我的方法试过了。修改 _buildExpandableContent 如下。

    _buildExpandableContent(Vehicle vehicle, index) {
    return List.generate(vehicle.contents.length, (index) {
      return ListTile(
        title: Text(
          vehicle.contents[index],
          style: new TextStyle(fontSize: 18.0),
        ),
        leading: Icon(vehicle.icon),
        tileColor: _selectedIndex == index ? Colors.blue : null,
        onTap: () {
          setState(() {
            _selectedIndex = index;
          });
        },
      );
    });
  }

为了您的参考,我在下面附上了您的样品的图片,它处于可运行状态。

Demo Picture