当点击另一个ExpansionTile时关闭ExpansionTile的方法是什么?

7

我有一个带有ListTile的ExpansionTile列表在抽屉中。我的目标是,当我点击一个ExpansionTile时,另一个ExpansionTile必须折叠起来。我已经陷入这个问题两天了,但找不到答案。有人知道如何以编程方式折叠ExpansionTile吗?

注意:

我不想弄乱小部件的动画。

以下是我的代码:

ListView.builder(
                itemCount: userList.length,
                shrinkWrap: true,
                itemBuilder: (BuildContext context, findex) {
                  return ExpansionTile(
                    key: Key(findex.toString()),
                    title: Text(userList[findex].parentdata[0].title,
                      style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold,color: Colors.black),
                    ),
                    onExpansionChanged: (value) {
                    },
                    children: [
                      ListView.builder(
                        itemCount: userList[findex].document.length,
                        shrinkWrap: true,
                        itemBuilder: (BuildContext context, sindex) {
                          return ListTile(
                            title: Text(
                                userList[findex].document[sindex].title,
                              style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold,color: Colors.black),
                            ),
                            onTap: () {
                              print(
                                  userList[findex].document[sindex].title);
                            },
                          );
                        },
                      ),
                    ],
                  );
                },
              ),

1
https://github.com/flutter/flutter/issues/60387 - aoiTenshi
5个回答

5

尝试以下代码

声明一个整型变量

int selectedTile = -1;

你的小部件
ListView.builder(
  key: Key(selectedTile.toString()),
  itemCount: 5,
  itemBuilder: (context, index) {
    return ExpansionTile(
      key: Key(index.toString()),
      initiallyExpanded: index == selectedTile,
      title: Text('ExpansionTile $index'),
      subtitle: Text('Trailing expansion arrow icon'),
      children: [
        ListTile(
          title: Text('This is tile number $index'),
        ),
      ],
      onExpansionChanged: ((newState) {
        if (newState)
          setState(() {
            selectedTile = index;
          });
        else
          setState(() {
            selectedTile = -1;
          });
      }),
    );
  },
);

1
它正在工作。但在我的情况下,上面的ExpansionTile键不起作用。我使用了这个 - key: UniqueKey(),而不是那个。 - Ilyas Arafath
在我的情况下,如果您使用了 key: UniqueKey(),那么上述密钥是有效的,我已经检查过两者都可以工作。感谢分享。 - Ravindra S. Patil

2

使用ExpansionPanel小部件。

您需要创建一个变量并维护扩展面板索引的扩展状态。

expansionCallback: (int index, bool isExpanded) {
        setState(() {
          // when any of expansionPanel is Tapped
          // set all expansion to false
          for(int i = 0; i<_data.length; i++){
            _data[i].isExpanded = false;
          }
          // then set the tapped index to its state
          _data[index].isExpanded = !isExpanded;
        });
      },

这里有一个展开面板的实时演示


ExpansionPanel 小部件中,我们只能点击图标。如果我们点击文本,将不会有任何响应。 - Senthur Kumaran
在ExpansionPanel中设置canTapOnHeader: true。 参考:https://api.flutter.dev/flutter/material/ExpansionPanel/canTapOnHeader.html - Bharath

1
key: index == lastOne ? const Key("selected") : Key(index.toString()),
                                                initiallyExpanded: index == selectedIndex,
                                                expandedCrossAxisAlignment: CrossAxisAlignment.start,
                                                onExpansionChanged: ((newState) {
                                                  lastOne = selectedIndex;
                                                  if (newState) {
                                                    setState(() {
                                                      selectedIndex = index;
                                                    });
                                                  } else {
                                                    setState(() {
                                                      selectedIndex = -1;
                                                    });
                                                  }
                                                }),

这样你也可以拥有动画效果


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

0
试试这个:
创建一个变量:int selected = -1; 还有listview
ListView.builder(
          itemCount: 10,
          shrinkWrap: true,
          itemBuilder: (BuildContext context, findex) {
            return ExpansionTile(
              initiallyExpanded: findex == selected,
              key: Key(selected.toString()),
              title: Text(userList[findex].parentdata[0].title,
                style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold,color: Colors.black),
              ),
              onExpansionChanged: (newState) {
                setState(() {
                  selected = findex;
                });
              },
              children: [
                ListView.builder(
                  itemCount: 10,
                  shrinkWrap: true,
                  itemBuilder: (BuildContext context, sindex) {
                    return ListTile(
                      title: Text(
                        userList[findex].document[sindex].title,
                        style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold,color: Colors.black),
                      ),
                      onTap: () {
                        print(userList[findex].document[sindex].title);
                      },
                    );
                  },
                ),
              ],
            );
          },
        ),

这个有问题。initiallyExpanded 属性只在创建 ExpandedTile Widget 时调用。因此,在每次点击时传递布尔值到 initiallyExpanded 属性是没有意义的。 - Senthur Kumaran
这对我有效,但是当我从一个ExpansionTile打开到另一个ExpansionTile时,动画不够流畅。有什么好的想法吗?谢谢。 - Soveyyy

0

确保ExpansionTile在有状态的小部件中

   ListView.builder(
                        itemCount: 5,
                          shrinkWrap: true,
                          itemBuilder: (BuildContext context, index) {
                            return CustomExpansionTile(index: index);
                          },
                        ),

// 扩展瓷砖小部件

       class CustomExpansionTile extends StatefulWidget {
              final int index;
            
              const CustomExpansionTile({Key? key, required this.index}) : super(key: key);
            
              @override
              State<CustomExpansionTile> createState() => _CustomExpansionTileState();
            }
            
            class _CustomExpansionTileState extends State<CustomExpansionTile> {
              int selectedIndexExpansionTile = -1;
            
              @override
              Widget build(BuildContext context) {
                return ExpansionTile(
                    initiallyExpanded: widget.index == selectedIndexExpansionTile,
                    key: Key(selectedIndexExpansionTile.toString()),
                    title: Text(
                      widget.index.toString(),
                    ),
                    onExpansionChanged: (newState) {
                 
                      if (newState) {
                        selectedIndexExpansionTile = widget.index;
                      } else {
                        selectedIndexExpansionTile = -1;
                      }
                      setState(() {});
                    },
                    children: [Text(widget.index.toString())]);
              }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接