我有一个带有大量不同视图的TabBarView()。我希望它们是一个顶部有TextField的列,下面是ListView.Builder(),但两个小部件应该在同一个可滚动区域(scrollview)。我实现它的方式引发了一些错误:
@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: new TextField(
decoration: new InputDecoration(
hintText: "Type in here!"
),
)
),
new ListView.builder(
itemCount: _posts.length, itemBuilder: _postBuilder)
],
);
}
错误:
I/flutter (23520): The following assertion was thrown during performResize():
I/flutter (23520): Vertical viewport was given unbounded height.
I/flutter (23520): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter (23520): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter (23520): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter (23520): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter (23520): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter (23520): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter (23520): the height of the viewport to the sum of the heights of its children.
我读到了在Expanded-Area中堆叠ListView.builder(),但它使文本字段变得“粘”,这不是我想要的。 :-)
我也遇到过CustomScrollView,但没有完全理解如何实现它。
提前致谢!
答案 0 :(得分:23)
将ListView放在Expanded
窗口小部件中可以解决您的问题:
@override
Widget build(BuildContext context) {
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: new TextField(
decoration: new InputDecoration(
hintText: "Type in here!"
),
)
),
new Expanded(child: ListView.builder(
itemCount: _posts.length, itemBuilder: _postBuilder))
],
);
}
答案 1 :(得分:8)
解决方案
SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
此处使用了两个属性
shrinkWrap: true
仅占用所需的空间(当有更多项目时,它仍会滚动)。
physics: NeverScrollableScrollPhysics()
滚动物理,不允许用户滚动。仅表示Column + SingleChildScrollView滚动工作。
答案 2 :(得分:7)
在 ListView.Builder()中使用 physics:NeverScrollableScrollPhysics()和 shrinkWrap:true 并享受
答案 3 :(得分:6)
这是解决方案:
SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
children: <Widget>[
Text('Hey'),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount:18,
itemBuilder: (context,index){
return Text('Some text');
})
],
),
),
答案 4 :(得分:2)
只需添加
Column(
mainAxisSize: MainAxisSize.max, //Add this line onyour column
children:[
SomeWidget(),
Expanded(child:ListView.builder())
]
)
答案 5 :(得分:1)
错误原因:
Column
沿主轴方向(垂直轴)扩展到最大尺寸,ListView
解决方案
您需要限制ListView
的高度,以便它可以扩展以匹配Column
,有几种方法可以解决此问题,在此列出了一些方法:
如果要允许ListView
占用Column
内的所有剩余空间,请使用Flexible
。
Column(
children: <Widget>[
Flexible(
child: ListView(...),
)
],
)
如果要将ListView
限制为某些height
,则可以使用SizedBox
。
Column(
children: <Widget>[
SizedBox(
height: 200, // constrain height
child: ListView(),
)
],
)
如果您的ListView
很小,则可以尝试在其上使用shrinkWrap
属性。
Column(
children: <Widget>[
ListView(
shrinkWrap: true, // use it
)
],
)
答案 6 :(得分:1)
就未来而言,我做到了:
SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text("Hey ho let's go!"),
Flexible(
child: FutureBuilder(
future: getData(),
builder: (BuildContext context,
AsyncSnapshot<List<Sale>> snapshot) {
if (snapshot.connectionState != ConnectionState.done ||
snapshot.hasData == null) {
return CircularProgressIndicator();
} else {
data = snapshot.data;
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return dataItemWidget(size, data[index], context);
},
itemCount: data.length,
);
}
},
),
),
],
),
),
答案 7 :(得分:0)
Column
不可滚动,这就是为什么顶部的TextField
不会滚动,但底部的ListView
会滚动。
我认为解决此问题的最佳方法是将TextField
作为ListView
中的第一项。
因此,您不需要列,您的父窗口小部件是ListView
,其子窗口是TextField
,其后是您使用_postBuilder
构建的其余项目。
答案 8 :(得分:0)
最好的方法是使列成为可滚动的,方法是使SingleChildScrollView的列成为子代,然后将相同的ScrollController分配给SingleChildScrollView和ListView.builder。这将使文本字段和下面的ListView可滚动。
答案 9 :(得分:0)
使用 Expanded 小部件进行约束,而不会使这些像素溢出:)
Column(
children: <Widget>[
Expanded(
child: ListView(),
),
Expanded(
child: ListView(),
),
],
)
答案 10 :(得分:0)
只需在 ListView.builder()中添加 physics:NeverScrollableScrollPhysics(),即可滚动
答案 11 :(得分:0)
在physics: NeverScrollableScrollPhysics()
方法内添加Listview.builder()
,嵌套的Listview
将滚动
答案 12 :(得分:0)
enter code here
收缩包装:假,
滚动方向:Axis.horizontal,
itemCount: 3,
itemBuilder:(上下文,索引){
返回行(
crossAxisAlignment: CrossAxisAlignment.start,
孩子们: [
文本(“你好”),
],
);
}), )
], );答案 13 :(得分:-1)
这是一个有效的解决方案:
class NestedListExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
const SliverToBoxAdapter(
child: Text('Header'),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
return ListTile(title:Text('Item $index'));
},
),
),
],
);
}
}
这是飞镖板上的preview。
您可以将SliverToBoxAdapter用于其他子项,因为只有Sliver可以是CustomScrollView的直接子项。
如果所有列表项的高度都相同,则可以使用SliverFixedExtentList,这样效率更高,因为不是每个孩子的身高都是即时计算出来的,但是您必须知道确切的像素高度。您还可以使用SliverPrototypeExtentList,在其中提供列表中的第一项(原型),所有其他子级将使用原型的高度,因此您无需知道确切的像素高度