Flutter踩坑:ListView布局报错,RenderFlex children have non-zero flex but incoming height constraints are...

完整报错信息:

RenderFlex children have non-zero flex but incoming height constraints are unbounded.

When a column is in a parent that does not provide a finite height constraint, for example if it is in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.

如图,想要实现的效果是,左侧标题正常居中,但文字居底部显示

那么看到这个布局最容易想到的办法是,因为左侧竖直排列的两个控件,父控件是Column,那么我们可以给标题控件使用Expanded来包装,Expanded的作用是填充剩余空间,和安卓的layout_weight含义差不多。然后时间就可以自然的被挤到底部。

但是实际上按这个思路实现的话,却报出了这个异常。

flutter的文章较少,网上不容易找到答案,在尝试了多遍,使用伪代码复现问题:

Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child:ListView(
shrinkWrap: true,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Column(
children: [
// Container(color: Colors.blue,child: Text(“bbb”)),
Expanded(child: Container(color: Colors.blue,child: Text(“bbb”))),
Container(color: Colors.green,child: Text(“ccc”)),
],
)),
Container(color: Colors.red,
child: Text(“aaa”),)
],
) ,
],) ,
)
],
)
测试多遍之后,发现了问题原因:

在Flutter的ListView的子View中,你可以在Row中使用Expanded填充水平方向的剩余空间,而无法在Column中使用Expanded填充垂直方向的剩余空间。

原因是ListView垂直方向的计算是包裹子View的,也就是说子View必须有一个明确的高度,或者尽可能小的高度,而不能是无限高。
Row是横向排列,在Row中使用Expanded是填充水平方向的剩余空间,这和ListView的这一特性没有冲突,可以使用。

而Column是竖直排列,在Column中使用Expanded是填充竖直方向的剩余空间,这将和ListView的这一特性发生冲突,因为ListView将无法计算自己的子View的高度。

这么解释看起来似乎也蛮合理,但是我们的子View并不是没有一个明确高度呀,他的右侧图片部分明显比左侧文案部分要高, ListView在绘制这个子View的时候,智能一点,直接使用右侧图片的高度,作为子view的整体高度不就ok了吗?

安卓里面就是系统这样智能处理掉的,而在Flutter中却报错。

好吧,那我们只能使用Flutter的办法去解决这个问题:

IntrinsicHeight可以根据子控件的高度,智能调整自身高度

把这个控件加在itemVIew的最外层,把Row给包括起来。

IntrinsicHeight可以根据子控件(左侧文案和右侧图片),智能选择一个合适的高度调整自身,使得ListView的子View的高度是确切的,这样ListView便不会因为子View想要无限高,而自己又要包括子View而报错了。

最终解决的代码如下:

Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: ListView(
shrinkWrap: true,
children: [
IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Column(
children: [
// Container(color: Colors.blue,child: Text(“bbb”)),
Expanded(
child: Container(
color: Colors.blue, child: Text(“bbb”))),
Container(color: Colors.green, child: Text(“ccc”)),
],
)),
Container(
color: Colors.red,
child: Text(“aaa”),
)
],
),
),
],
),
)
],
))

效果:

————————————————
版权声明:本文为CSDN博主「kaixuan_dashen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kaixuan_dashen/article/details/102308861

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值