这是我的代码:
@override
Widget build(BuildContext context) {
return new Material(
color: Colors.deepPurpleAccent,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children:<Widget>[new GridView.count(crossAxisCount: _column,children: new List.generate(_row*_column, (index) {
return new Center(
child: new CellWidget()
);
}),)]
)
);
}
例外情况如下:
I/flutter ( 9925): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 9925): The following assertion was thrown during performResize():
I/flutter ( 9925): Vertical viewport was given unbounded height.
I/flutter ( 9925): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 9925): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 9925): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter ( 9925): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter ( 9925): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter ( 9925): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter ( 9925): the height of the viewport to the sum of the heights of its children.
I/flutter ( 9925):
I/flutter ( 9925): When the exception was thrown, this was the stack:
I/flutter ( 9925): #0 RenderViewport.performResize.<anonymous closure> (package:flutter/src/rendering/viewport.dart:827:15)
I/flutter ( 9925): #1 RenderViewport.performResize (package:flutter/src/rendering/viewport.dart:880:6)
I/flutter ( 9925): #2 RenderObject.layout (package:flutter/src/rendering/object.dart:1555:9)
我们可以用两种方法来解决上述问题
1. 使用灵活的部件,
Flexible小部件可以在Row、Column和Flex中使用。扩展以填充主轴中的可用空间的灵活性(例如,水平扩展[Row]或垂直扩展[Column])
但是,请记住,与Expanded不同,The Flexible小部件不需要子部件填充可用空间。所以,最好使用Flexible。
Column(
children: <Widget>[
Flexible(
child: ListView(...),
),
],
)
2. 使用shrinkWrap: true
使用shrinkWrap为true,我们告诉Listview渲染它的List到可用空间,而不是在剩余屏幕以下。
Column(
children: <Widget>[
ListView(
shrinkWrap: true,
),
],
)
此外,物理属性可以用来允许/禁止滚动Listview
停止滚动
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
),
允许滚动
ListView(
shrinkWrap: true,
physics: ScrollPhysics(),
),
我们可以用两种方法来解决上述问题
1. 使用灵活的部件,
Flexible小部件可以在Row、Column和Flex中使用。扩展以填充主轴中的可用空间的灵活性(例如,水平扩展[Row]或垂直扩展[Column])
但是,请记住,与Expanded不同,The Flexible小部件不需要子部件填充可用空间。所以,最好使用Flexible。
Column(
children: <Widget>[
Flexible(
child: ListView(...),
),
],
)
2. 使用shrinkWrap: true
使用shrinkWrap为true,我们告诉Listview渲染它的List到可用空间,而不是在剩余屏幕以下。
Column(
children: <Widget>[
ListView(
shrinkWrap: true,
),
],
)
此外,物理属性可以用来允许/禁止滚动Listview
停止滚动
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
),
允许滚动
ListView(
shrinkWrap: true,
physics: ScrollPhysics(),
),
所以,每个人都上传了答案,但没有人愿意解释原因:
我将复制关于shrinkWrap的文档:
Whether the extent of the scroll view in the [scrollDirection] should be
determined by the contents being viewed.
If the scroll view does not shrink wrap, then the scroll view will expand
to the maximum allowed size in the [scrollDirection]. If the scroll view
has unbounded constraints in the [scrollDirection], then [shrinkWrap] must
be true.
Shrink wrapping the content of the scroll view is significantly more
expensive than expanding to the maximum allowed size because the content
can expand and contract during scrolling, which means the size of the
scroll view needs to be recomputed whenever the scroll position changes.
Defaults to false.
所以,从文档的词汇表来看,这里发生的是我们的ListView处于一个无限约束的情况(在我们滚动的方向上),因此ListView会抱怨:
... 垂直视口被赋予无限的垂直空间
它需要扩展。
通过简单地将shrinkWrap设置为true,将确保它包装由内容定义的大小。示例代码说明:
// ...
ListView(
// Says to the `ListView` that it must wrap its
// height (if it's vertical) and width (if it's horizontal).
shrinkWrap: true,
),
// ...
这就是你的代码,尽管如此,@Rémi建议是最好的,使用Align而不是Column。
我想发布另一个答案,因为许多答案(包括已接受的答案!)建议在ListView.builder中使用shrinkWrap: true。虽然这消除了错误,但在这种情况下,由于性能原因,这种解决方案并不理想。Flutter设计了无限大小的ListView,专门在必要时阻止这种行为!
收缩包装滚动视图的内容比展开到允许的最大大小要昂贵得多,因为内容可以在滚动期间展开和收缩,这意味着每当滚动位置发生变化时,都需要重新计算滚动视图的大小。
在某些情况下/设备,这个属性导致故障滚动和动画滞后在我的项目。即使延迟不明显,这个属性也会影响滚动性能。
OP显示他正在为ListView创建一个小(有限)数量的子节点。如果我们想要解决这些列表的错误,谷歌建议使用一个Flexible小部件,即在列表本身上使用Expanded(带有flex 1的Flexible)。
Expanded(
child: ListView(
...
),
)
这里还有其他布局问题,但垂直视口无界高度是因为ListView没有一个限制其大小的父类。
这通常发生在你试图在一个列中使用一个ListView/GridView时,有很多方法来解决它,我在这里列出了几个。
将ListView包装为Expanded
列(
孩子们:<部件> (
Expanded(// wrap in Expanded .
孩子:列表视图(…),
),
),
)
在sizebox中包装ListView并给出一个有界的高度
列(
孩子们:<部件> (
SizedBox (
高度:400,//固定高度
孩子:列表视图(…),
),
),
)
在ListView中使用shrinkWrap: true。
列(
孩子们:<部件> (
列表视图(
shrinkWrap: true, //使用这个
),
),
)