简体   繁体   English

Flutter:如何在 GridView 或 Wrap 小部件中展开/折叠(显示/隐藏)一行

[英]Flutter: How to expand/collapse (show/hide) a Row in a GridView or Wrap widget

I'm trying to build a GridView where selected the item can expand/collapse (show/hide) a row in the immediate consecutive row of the selected item, like an information box.我正在尝试构建一个 GridView ,其中选定的项目可以展开/折叠(显示/隐藏)所选项目的紧邻连续行中的一行,如信息框。

On the screenshot below I'm showing an example where the Node 001 is selected.在下面的屏幕截图中,我展示了一个选择节点 001 的示例。

Don't know if I can achieve this with GridView widget or Wrap Widget, but any help will be very appreciated.不知道我是否可以使用 GridView 小部件或 Wrap Widget 来实现这一点,但我们将不胜感激。

Thanks in advance for your support.预先感谢您的支持。

Sample mockup screenshot:样机截图示例: 样机截图示例

My actual GridView code:我的实际 GridView 代码:

GridView.builder(
              shrinkWrap: true,
              padding: EdgeInsets.zero,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 4,
                  crossAxisSpacing: 5,
                  mainAxisSpacing: 5,
                  mainAxisExtent: 40),
              itemCount: nodes.length,
              itemBuilder: (BuildContext context, int index) {
                return TextButton(
                  onPressed: (selectedNode == nodes[index].slaveId)
                      ? () {}
                      : () =>
                          Provider.of<SelectedNode>(context, listen: false)
                              .value = nodes[index].slaveId!,
                  style: TextButton.styleFrom(
                      backgroundColor:
                          (selectedNode == nodes[index].slaveId)
                              ? selectedColor
                              : unselectedColor),
                  child: Text(
                      'Node ${nodes[index].slaveId.toString().padLeft(3, '0')}'),
                );
              },
            )

Modified code:修改后的代码:

SizedBox(
        width: double.infinity,
        child: SizedBox(
          height: MediaQuery.of(context).size.height / 3.2,
          child: GridView.builder(
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 4,
                  crossAxisSpacing: 5,
                  mainAxisSpacing: 5,
                  mainAxisExtent: 40),
              itemCount: [1, 2, 3, 4, 5, 6, 7, 8, 9].length + 1,
              clipBehavior: Clip.none,
              itemBuilder: (context, index) {
                if (index != 1) {
                  return Stack(
                    clipBehavior: Clip.none,
                    children: [
                      TextButton(
                        onPressed: (selectedNode == nodes[index].slaveId)
                            ? () {}
                            : () => Provider.of<SelectedNode>(context,
                                    listen: false)
                                .value = nodes[index].slaveId!,
                        style: TextButton.styleFrom(
                            backgroundColor:
                                (selectedNode == nodes[index].slaveId)
                                    ? selectedColor
                                    : unselectedColor),
                        child: Text(
                            'Node ${nodes[index].slaveId.toString().padLeft(3, '0')}'),
                      ),
                      index == 0
                          ? Positioned(
                              child: Text('1hjkkhj'),
                              bottom: -20,
                              left: 0,
                              right: 0,
                            )
                          : SizedBox(),
                    ],
                  );
                } else {
                  return TextButton(
                    onPressed: (selectedNode == nodes[index].slaveId)
                        ? () {}
                        : () => Provider.of<SelectedNode>(context,
                                listen: false)
                            .value = nodes[index].slaveId!,
                    style: TextButton.styleFrom(
                        backgroundColor:
                            (selectedNode == nodes[index].slaveId)
                                ? selectedColor
                                : unselectedColor),
                    child: Text(
                        'Node ${nodes[index].slaveId.toString().padLeft(3, '0')}'),
                  );
                }
              }),
        ),
      ),

you can get the selected index and dived it to 4 and round up the result should give you the row number which that item click, so call this selectedRow row.您可以获得选定的索引并将其潜水到 4 并四舍五入结果应该为您提供该项目单击的行号,因此调用此selectedRow行。 in your grid view you can use selectedRow and add empty space for the next row.在您的网格视图中,您可以使用selectedRow并为下一行添加空白空间。 After that change item widget that you show in grid view and add it in a stack and add another container that contain your expanded widget.之后更改您在网格视图中显示的项目小部件并将其添加到堆栈中并添加另一个包含扩展小部件的容器。 also remember that you should set stack and grid view clipBehavior to Clip.none .还请记住,您应该将堆栈和网格视图clipBehavior设置为Clip.none

something like this:像这样的东西:

ListView.builder(
            padding: const EdgeInsets.all(8),
            itemCount: [1, 2, 3].length + 1,
            clipBehavior: Clip.none,
            itemBuilder: (context, index) {
              if (index != 2) {
                return Stack(
                  clipBehavior: Clip.none,
                  children: [
                    Text('dasdasdasd'),
                    index == 1
                        ? Positioned(
                            child: Text('1hjkkhj'),
                            bottom: -20,
                            left: 0,
                            right: 0,
                          )
                        : SizedBox(),
                  ],
                );
              } else {
                return SizedBox(
                  height: 20,
                );
              }
            })

I know it is listview but the concept work in gridview too.我知道它是列表视图,但这个概念也适用于 gridview。

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

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