没有明确高度的水平 ListView 颤动

Posted

技术标签:

【中文标题】没有明确高度的水平 ListView 颤动【英文标题】:Horizontal ListView flutter WITHOUT explicit height 【发布时间】:2019-07-07 05:08:54 【问题描述】:

我正在尝试创建一个没有预设高度的水平滚动listview.builder()

我尝试将 shrinkwrap 设置为 true 并将其包装在 Expanded/Flexible 中。

目前达到预期效果的唯一方法(我发现)是根据这个答案 (Flutter: Minimum height on horizontal list view) 在列内的 singlechildscrollview 内换行。

该方法的问题在于没有构建器方法可以将动态数据加载到singlechildscrollview 内的卡片中。

我的问题是我如何创建一个水平的listview,它通过嵌套在singlechildscrollview (Flutter: Minimum height on horizontal list view) 内的row 生成输出但使用构建器方法?

灵活

Scaffold(
  body: Container(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Flexible(
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            itemCount: 3,
            itemBuilder: (BuildContext context, int index) 
              return FeaturedCard();
            ,
          ),
        ),
        Flexible(
          child: ListView.builder(
            shrinkWrap: true,
            itemCount: 10,
            itemBuilder: (BuildContext context, int index) 
              return FeaturedCard();
            ,
          ),
        ),
      ],
    ),
  ),
)

结果:https://i.stack.imgur.com/XKiWo.jpg

singlechildscrollview内嵌套row(有效的方法)

 Container(
  padding: EdgeInsets.only(top: 16, bottom: 8),
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
      SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: <Widget>[
            FeaturedCard(),
            FeaturedCard(),
          ],
        ),
      ),
    ],
  ),
)

结果: https://i.stack.imgur.com/va3TY.jpg

注意使用灵活时卡内增加的空间(这实际上在不同设备上呈现更糟)

【问题讨论】:

【参考方案1】:

为将答案编辑到问题中的 OP 发布答案

通过创建自定义构建器方法解决了这个问题,如下所示:

Widget _buildFeaturedCards(List<Product> product) 
  final cards = <Widget>[];
  Widget FeautredCards;

  if (product.length > 0) 
    for (int i = 0; i < product.length; i++) 
      cards.add(FeaturedCard(product[i]));
      print(product.length);
    
    FeautredCards = Container(
      padding: EdgeInsets.only(top: 16, bottom: 8),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Row(children: cards),
          ),
        ],
      ),
    );
   else 
    FeautredCards = Container();
  
  return FeautredCards;

这会预先创建必要的滚动小部件,而不是像 ListView.builder 那样懒惰地创建。

【讨论】:

表达式不计算为函数,因此无法调用。 @JohnJoe 不确定您所说的“表达”是什么意思。你必须更具体。您还向错误的人发送消息。这是OP的解决方案。 @JohnJoe FeaturedCard 未在此范围内定义。你期待什么? cards 是 List widget,但 FeaturedCard 是对象。你确定代码可以工作吗?错误:无法将参数类型“FeaturedCard”分配给参数类型“Widget” @ChristopherMoore 感谢您发布此消息! @JohnJoe FeaturedCardWidget 混淆可能是由于非骆驼案例命名造成的,对此感到抱歉!【参考方案2】:

Flutter 框架只有在构建小部件后才能知道它的高度。

如果您正在动态构建ListView 子级,它无法计算ListView 的所需高度,直到它的所有子级都已构建完毕,这可能永远不会发生(无限ListView)。

您可以给 ListView 一个固定的高度并动态构建它的孩子,或者让 ListView's 的高度取决于它的孩子,在这种情况下,您需要预先构建它的所有孩子。

【讨论】:

先造一个孩子是什么意思? @TSR 这意味着孩子不能被懒惰地构建(按需)。基本上,你不能使用ListView.builder。 OP 在他们的问题中发布了一个解决方案,我已将其编辑并发布在社区 wiki 中。他们使用SingleChildScrollViewRow 作为替代。

以上是关于没有明确高度的水平 ListView 颤动的主要内容,如果未能解决你的问题,请参考以下文章

在颤动的页面上同时使用水平和垂直 listview.builder

在具有动态高度的同一页面上颤动两个 listview.builder

如何在颤动的列表视图中嵌套列表视图?

如何在颤动/飞镖的 ListView 项目中更改背景颜色

如何在颤动的Listview中显示字符串列表

一些滚动后颤动ListView KeepAlive