ListView Builder 与 SingleChildScrollView + Row 组合

ListView Builder vs SingleChildScrollView + Row combo

我想在我的应用程序中制作响应式 UI。在我的主页中,我有 ScrollView->Column->childrens 结构。

当我想在 column 中使用 horizontal Listview.builder 时,它会抛出错误,因为高度是 unbounded。我用容器包裹我的 listview builder 来修复它,我给这个容器一个高度值。但我不想给这个高度硬编码,

我想让我的 container 高度达到它自己 child 的高度。我搜索了它并找到了 ScrollView->Row->list.generate 而不是 ListView.Builder 的解决方案。但是弄成这样可以吗?它会导致性能问题还是不好的做法?

我的清单并不大。它最多有 20 个元素

例如这个抛出错误:

@override   Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: SingleChildScrollView(
          child: Column(
        children: [
          ListView.builder(
            itemCount: 5,
            physics: NeverScrollableScrollPhysics(),
            scrollDirection: Axis.horizontal,
            shrinkWrap: true,
            itemBuilder: (context, index) {
              return Container(
                width: 200,
                height: 200,
              );
            },
          )
        ],
      )),
    );   }

但这不会引发错误

@override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
        child: Column(
      children: [
        SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(
            children: List.generate(
                5,
                (index) => Container(
                      width: 200,
                      height: 200,
                      color: Colors.red,
                    )),
          ),
        ),
      ],
    ));
  }

为大家澄清一下:

ListView 会“延迟”生成它们的 children - 这意味着它们在显示在屏幕上之前不会被绘制。这当然意味着他们不知道他们物品的高度。

例如,如果 ListViews children 的高度类似于此列表:

ooooOooo

但屏幕上只显示了这一部分:

oooo |呜呜呜

并且 ListView 将其高度设置为适合“o”,然后当它最终出现在屏幕上时将无法适合“O”。


另一方面,行 do 在 spawn 上绘制所有 children,这意味着,当它们这样做时知道所有小部件的大小,它们很快就会变得非常慢。

我会 而不是 建议在具有 2 位数+ children 的行内使用图像,因为它们不仅会滞后在他们最初的抽奖中,而且当用户在包含所述行的页面中做其他事情时 - 例如滚动 up/down 页面。

在测试时我发现只有 30 children 个相同堆栈的行(IconImage 顶部的一个小 AssetImage)在滚动时会滞后整个页面 up/down - 甚至不会沿行本身滚动。


我为您推荐的解决方案 Ahmet, 即使您不想 hard-code ListView 的高度,也可以使用以下方法解决和设置 ListView 的高度:

MediaQuery.of(context).size.height * (percentage of screen's height you'd like for the ListView to take).