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的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 另一个Listview内的Listview.builder
Flutter - 如何访问 ListView.builder 中的一个元素?