【flutter浆糊踩坑记】使用Expanded布局时报错The following assertion was thrown during performLayout

 浆糊之家   2019-11-05 17:17   4 views 热度值  网名www.fybqq.com

在使用Row和Column布局,在用了Expanded组件时报错如下:

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()组件的结构,

children (using Flexible rather than Expanded). This will allow the flexible children to size

从上方线索查找问题,这时候我就想到,我当时是直接在底层Row()组件中直接利用撑开组件Expanded,而上一层父组件或某个N父组件大小是特别灵活没有定大小是弹性的。

所以整体在flutter中无法计算大小来撑开布局,这时候我就把父组件上面的Row内也使用了Expanded组件撑开才得以不报错

以下粘贴我的出问题的代码

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里面才可以计算组件盒子大小

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计算组件不正确,直接抛出父组件一直是弹性无法正常计算宽度撑开。

 发表评论


表情