在使用Row和Column布局,在用了Expanded组件时报错如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
I/flutter (14104): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (14104): The following assertion was thrown during performLayout(): I/flutter (14104): RenderFlex children have non-zero flex but incoming width constraints are unbounded. I/flutter (14104): When a row is in a parent that does not provide a finite width constraint, for example if it is in a I/flutter (14104): horizontal scrollable, it will try to shrink-wrap its children along the horizontal axis. Setting a I/flutter (14104): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining I/flutter (14104): space in the horizontal direction. I/flutter (14104): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child I/flutter (14104): cannot simultaneously expand to fit its parent. I/flutter (14104): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible I/flutter (14104): children (using Flexible rather than Expanded). This will allow the flexible children to size I/flutter (14104): themselves to less than the infinite remaining space they would otherwise be forced to take, and I/flutter (14104): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum I/flutter (14104): constraints provided by the parent. I/flutter (14104): If this message did not help you determine the problem, consider using debugDumpRenderTree(): I/flutter (14104): https://flutter.dev/debugging/#rendering-layer I/flutter (14104): http://api.flutter.dev/flutter/rendering/debugDumpRenderTree.html I/flutter (14104): The affected RenderFlex is: I/flutter (14104): RenderFlex#ad712 relayoutBoundary=up14 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE(creator: Row ← Column ← Row ← Padding ← Semantics ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#e6eab ink renderer] ← NotificationListener<LayoutChangedNotification> ← CustomPaint ← _ShapeBorderPaint ← PhysicalShape ← ⋯, parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size), constraints: BoxConstraints(unconstrained), size: MISSING, direction: horizontal, mainAxisAlignment: start, mainAxisSize: max, crossAxisAlignment: center, textDirection: ltr, verticalDirection: down) I/flutter (14104): The creator information is set to: I/flutter (14104): Row ← Column ← Row ← Padding ← Semantics ← DefaultTextStyle ← AnimatedDefaultTextStyle ← I/flutter (14104): _InkFeatures-[GlobalKey#e6eab ink renderer] ← NotificationListener<LayoutChangedNotification> ← I/flutter (14104): CustomPaint ← _ShapeBorderPaint ← PhysicalShape ← ⋯ I/flutter (14104): The nearest ancestor providing an unbounded width constraint is: RenderFlex#63b6e relayoutBoundary=up12 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE: I/flutter (14104): creator: Row ← Padding ← Semantics ← DefaultTextStyle ← AnimatedDefaultTextStyle ← I/flutter (14104): _InkFeatures-[GlobalKey#e6eab ink renderer] ← NotificationListener<LayoutChangedNotification> ← I/flutter (14104): CustomPaint ← _ShapeBorderPaint ← PhysicalShape ← _MaterialInterior ← Material ← ⋯ I/flutter (14104): parentData: offset=Offset(0.0, 0.0) (can use size) I/flutter (14104): constraints: BoxConstraints(w=361.4, 0.0<=h<=Infinity) I/flutter (14104): size: MISSING I/flutter (14104): direction: horizontal I/flutter (14104): mainAxisAlignment: start I/flutter (14104): mainAxisSize: max I/flutter (14104): crossAxisAlignment: start I/flutter (14104): textDirection: ltr I/flutter (14104): verticalDirection: down I/flutter (14104): See also: https://flutter.dev/layout/ I/flutter (14104): If none of the above helps enough to fix this problem, please don't hesitate to file a bug: I/flutter (14104): https://github.com/flutter/flutter/issues/new?template=BUG.md I/flutter (14104): I/flutter (14104): Widget creation tracking is currently disabled. Enabling it enables improved error messages. It can |
在报错时找到有效线索信息不多,因为结构创建和目前抛出来的错误还是有些差异,
但其中有一句是如下:
大小太过于灵活,当时我的代码是Row()组件内还套了Row()组件的结构,
1 |
children (using Flexible rather than Expanded). This will allow the flexible children to size |
从上方线索查找问题,这时候我就想到,我当时是直接在底层Row()组件中直接利用撑开组件Expanded,而上一层父组件或某个N父组件大小是特别灵活没有定大小是弹性的。
所以整体在flutter中无法计算大小来撑开布局,这时候我就把父组件上面的Row内也使用了Expanded组件撑开才得以不报错
PS:这里说明一下,你父层组件你是可以使用 外层包裹一个固定宽度组件方式来实现不报错,但局限了整体弹性布局业务考虑了!
以下粘贴我的出问题的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
class _SearchListState extends State<SearchList> { @override Widget build(BuildContext context) { return ListView.builder( itemCount: 1, itemBuilder: (BuildContext context, idx) { return Container( child: Card( margin: EdgeInsets.only(bottom: 10), // 外边距 elevation: 3, // 阴影大小 child: Padding( padding: EdgeInsets.fromLTRB(5, 15, 5, 15), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ // 此处没有进行Expanded组件撑开,所以里面嵌套的Row使用撑开组件会报错误 cardRigthWidget(), ], ), ), ), ); }, ); } Widget cardRigthWidget() { return Column( mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Row( children: <Widget>[ Expanded( child: RichText( text: TextSpan( text: '标题', style: TextStyle( color: Theme.of(context).primaryColor), // 设置默认文字样式 children: <TextSpan>[ TextSpan(text: 'title_mo_blockhain'), ], ), ), ), ], ), ], ); } } |
最后修复的代码,就是在最顶层Row组件内在加上一个Expanded撑开组件即可,这样flutter里面才可以计算组件盒子大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class _SearchListState extends State<SearchList> { @override Widget build(BuildContext context) { return ListView.builder( itemCount: 1, itemBuilder: (BuildContext context, idx) { return Container( child: Card( margin: EdgeInsets.only(bottom: 10), // 外边距 elevation: 3, // 阴影大小 child: Padding( padding: EdgeInsets.fromLTRB(5, 15, 5, 15), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ // 改造一下,父组件包裹Expanded撑开组件 Expanded( child: cardRigthWidget(), ), ], ), ), ), ); }, ); } // 。。。。其它代码还是之前的 } |
此时报错就顺序解决,渲染正常
总结:像flutter内不能像HTML一样写完全的flex弹性使用,多多少少还是有些坑点的,比如这次Row弹性组件内在套用了其它的Row,顶层必须先撑开计算,这样嵌套层的Row才能正常使用Expanded组件。
否则引起flutter计算组件不正确,直接抛出父组件一直是弹性无法正常计算宽度撑开。