Flutter - 另一个 Listview 中的 Listview.builder

Posted

技术标签:

【中文标题】Flutter - 另一个 Listview 中的 Listview.builder【英文标题】:Flutter - Listview.builder inside another Listview 【发布时间】:2019-04-27 04:05:17 【问题描述】:

我希望我的屏幕可以滚动,所以我将所有内容都放在 Listview 中。

现在我想在里面显示另一个 Listview 来显示 List 的详细信息。当我尝试这个时,会抛出一个错误——“扩展的小部件必须放在 Flex 小部件中。”

【问题讨论】:

在 listview.builder 中添加收缩包装:true 移除最顶部的容器或将其替换为列 【参考方案1】:

listView.builder 中添加shrinkWrap: true 并删除最上面的Container 或将其替换为Column

【讨论】:

谢谢,这对于将 listview.builder 放在 listView 中特别有用,但不使用 Expanded...【参考方案2】:

在 listview.builder 中添加shrinkWrap: true, physics: ScrollPhysics(),,在这种情况下,listview.builder 需要扩展父级。 physics: ScrollPhysics() 将允许它保持其状态而无需滚动回第一个项目。此外,如果您不希望用户滚动 listview.builder,您可以使用physics: NeverScrollableScrollPhysics()

【讨论】:

太棒了!感谢@CodeMemory,它非常适合具有动态数据的 ListView.builder。【参考方案3】:

我希望我的屏幕可以滚动,所以我将所有内容都放在 Listview 中。

我认为您应该使用带有条子的CustomScrollView。

如果这是您第一次听说条子,或者它们看起来有点吓人,我建议您阅读 Emily Fortuna 撰写的这篇出色的 article。

在你的情况下,我会这样做:

return CustomScrollView(
  slivers: <Widget>[
    SliverToBoxAdapter(
      // Put here all widgets that are not slivers.
      child: Container(),
    ),
    // Replace your ListView.builder with this:
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) 
          return ListTile();
        ,
      ),
    ),
  ],
);

【讨论】:

【参考方案4】:

在我的例子中,在 ListView.builder 中添加 physics: ScrollPhysics(), 使 ListView.builder 可滚动。

层次结构是 ListView > StreamBuilder > RefreshIndicator > ListView.builder

【讨论】:

【参考方案5】:

我在使用 两个 ListViews 时遇到了这个问题,一个在另一个里面。除了这个解决方法之外,没有什么对我有用。

在嵌套的 Listview 中,用一个 ConstrainedBox 覆盖它并给它一些较大的高度。并使用 'shrinkWrap: true' 两个 ListViews。由于收缩包装会修剪额外的空间,因此额外的高度不会成为问题。

Flexible(
  child: ListView(
    children: <Widget>[
      //other Widgets here ...
      ConstrainedBox(
        constraints: BoxConstraints(maxHeight: 1000), // **THIS is the important part**
        child: ListView.builder(
          shrinkWrap: true,
          itemBuilder: (context, index) => _buildRow(index),
          itemCount: _elements.length,
        ),
      ),
    ],
  ),
),

【讨论】:

【参考方案6】:

我能够通过将主列包装在 SingleChildScrollView 中来解决问题,然后将 ListView.builder 包装在 Container 中,为容器提供指定的高度,然后再次将该容器包装在 SingleChildScrollView 中。 我知道这很复杂,但它对我有用! 你可以通过代码有一个清晰的画面。

 Scaffold(
    appBar: AppBar(
      centerTitle: true,
      backgroundColor: Colors.black,
      title: Text("Welcome, $widget.myUser.name"),
      actions: [
        InkWell(
          child: Container(
            alignment: Alignment.center,
            padding: EdgeInsets.only(right: 20),
            child: Icon(Icons.settings),
          ),
          onTap: () ,
        ),
      ],
    ),
    body: Padding(
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: SingleChildScrollView(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: [
            _customerDetailsWidget(),
            SizedBox(
              height: 15,
            ),
            Container(
              child: Divider(
                color: Colors.grey[500],
              ),
            ),
            SizedBox(
              height: 15,
            ),
            _addProductText(),
            SingleChildScrollView(
                child: Container(
                  height: 500,
                  child: ListView.builder(
                    itemCount:1,
                    itemBuilder: (BuildContext context, int index) 
                      return Container(child: Text("HELLO WORLD"));
                    ,
                  ),
                ))
          ],
        ),
      ),
    ),
  ),

【讨论】:

谢谢。我在 ListView.build 中添加 SingleChildScrollView 将 shrinkWrap 值设置为 true。【参考方案7】:

这实际上取决于您的布局。可能的情况是:

使用ListView + ListView

如果你想给你的第二个ListView 全高。

ListView(
  children: [
    // Your other widgets ...
    ListView.builder(
      shrinkWrap: true, //    <-- Set this to true
      physics: ScrollPhysics(), // <-- Also change physics
      itemBuilder: ...,
    ),
  ],
)

使用ListView + ListView

如果你想限制第二个ListView的高度。

ListView(
  children: [
    // Your other widgets ...
    SizedBox( //             <-- Use SizedBox
      height: 160, 
      child: ListView.builder(
        itemBuilder: ...,
      ),
    ),
    // Your other widgets ...
  ],
)

使用Column + ListView

如果您的第一个 ListView 中没有太多(或太大)的孩子,请将其替换为 Column

Column(
  children: [
    // Your other widgets ...
    Expanded( //              <-- Use Expanded
      child: ListView.builder(
        itemBuilder: ...,
      ),
    ),
  ],
)

【讨论】:

以上是关于Flutter - 另一个 Listview 中的 Listview.builder的主要内容,如果未能解决你的问题,请参考以下文章

ListView Flutter 中的 ListViews

Flutter - 另一个Listview内的Listview.builder

Flutter - 如何访问 ListView.builder 中的一个元素?

Flutter:从 appbar 调用 listview builder 中的方法

无法在 Flutter 中添加 ListView

如何使用控制器 ListView Flutter