嵌套的 Listview 不水平滚动

Nested Listview not scrolling horizontally

我有一个相对复杂的 Listview 设置,其中一个 Listview 充当水平 Listview 的滚动父级,后者充当第三个垂直 Listview 的父级。

这是布局的总体思路的图像:https://cdn.discordapp.com/attachments/752981111738466467/895739370227773480/IMG_20211007_142732.jpg

我无法滚动中间的 Listview,即水平 Listview(图中标记为 2)。

ConstrainedBox(
        constraints: BoxConstraints(...),
        child: ListView.builder( // This is Listview 1
            controller: ScrollController(),
            itemCount: itemCount,
            itemBuilder: (context, worldIndex) {
              return ConstrainedBox(
                  constraints: BoxConstraints(...),
                  child: ListView.builder( // This is Listview 2
                      controller: ScrollController(),
                      itemCount: ...,
                      scrollDirection: Axis
                          .horizontal, // grows horizontally to show the hierarchy of one card (the card selected in the hierarchy above it, or for the first level, the world) to its children
                      itemBuilder: (context, index) {
                        ...
                        return ConstrainedBox(
                            constraints: BoxConstraints(...),
                            child: Padding(
                                padding: const EdgeInsets.all(4.0),
                                child: Container(
                                  decoration: ...,
                                  ),
                                  child: ListView.builder( // This is Listview 3
                                      controller: ScrollController(),
                                      itemCount: getNumChildren(index),
                                      itemBuilder: (context, index2) {
                                        return ...;
                                      }),
                                )));
                      }));
            }));

为简洁起见,我删除了代码的几个部分并用省略号替换了它们。我认为这些区域中的任何一个都不太可能导致 Listview 出现任何问题,但如果可能的话请告诉我。

编辑:除了水平 Listview 不滚动之外,我的代码已经可以正常工作。我的解决方案需要在树的每个级别(例如,图像中的 1、2 和 3)都有一个动态可扩展的 Listview。主要目标平台是 Windows.

我假设问题涉及 Listview 赢得 GestureArena 的问题,但我目前不知道如何解决该问题,提供一种滚动所有可用 Listviews 的方法。

在此先感谢您,希望您度过愉快的一天!

据我所知。也许您正在寻找这样的东西?我已经评论了您需要的 3 种类型的卷轴。如有不妥之处,请指出。

Widget build(BuildContext context) {
return MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  home: Scaffold(
    body: SingleChildScrollView(
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            for (var i = 0; i < 5; i++)
              // One big section in the largest col (1).
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  SizedBox(
                    height: 200.0,
                    child: ListView.builder(
                      // Horizontal item builder. (2)
                      shrinkWrap: true,
                      scrollDirection: Axis.horizontal,
                      itemCount: 10,
                      itemBuilder: (context, index) {
                        return SingleChildScrollView(
                          child: Column(
                            // Inside one vertical section. (3)
                            children: [
                              for (var i = 0; i < 5; i++)
                                ElevatedButton(
                                    onPressed: () {}, child: Text("OK")),
                            ],
                          ),
                        );
                      },
                    ),
                  ),
                ],
              ),
          ],
        ),
      ),
    ),
  ),
);
}

这个问题的解决方案是 Flutter 故意关闭了使用滚轮和拖动水平滚动 Windows 的能力(或者至少,根据我在 this issue).

中找到的内容

为了解决这个问题,他们制作了迁移指南 here

按照指南,覆盖使用的拖动设备以重新启用预期的拖动滚动非常简单。这仍然无法使用鼠标滚轮水平滚动,但对于我的代码来说这不是问题。

class CustomScrollBehavior extends MaterialScrollBehavior { // A custom scroll behavior allows setting whichever input device types that we want, and in this case, we want mouse and touch support.
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.mouse,
        PointerDeviceKind.touch,
      };
}

然后,在实际的 Listview 代码中,我们设置一个 ScrollConfiguration 并将这个新的 class 作为它的行为。

ScrollConfiguration(
  behavior: CustomScrollBehavior(),
  child: Listview.Builder(
    controller: ScrollController(),
    scrollDirection: Axis.horizontal,
    itemBuilder: (context, index) {
      ... 
    })