Flutter聊天界面添加消息后崩溃,RenderBox未布局问题求助
Flutter聊天界面添加消息后崩溃的渲染错误修复
问题现象
开发聊天界面时,初始运行正常,但添加消息到列表并展示时应用崩溃,抛出以下渲染错误:
RenderObject: RenderFlex#83717 relayoutBoundary=up8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> (can use size) constraints: BoxConstraints(0.0<=w<=430.0, 0.0<=h<=Infinity) size: MISSING direction: vertical mainAxisAlignment: start mainAxisSize: max crossAxisAlignment: center verticalDirection: down child 1: _RenderScrollSemantics#4f646 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.tight constraints: MISSING semantic boundary size: MISSING child: RenderPointerListener#8b994 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING behavior: deferToChild listeners: signal child: RenderSemanticsGestureHandler#12b20 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING behavior: opaque gestures: <none> child: RenderPointerListener#29265 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING behavior: opaque listeners: down, panZoomStart child 2: RenderConstrainedBox#5dfd5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: offset=Offset(0.0, 0.0); flex=null; fit=null constraints: MISSING size: MISSING additionalConstraints: BoxConstraints(0.0<=w<=Infinity, h=1.0) child: RenderPositionedBox#eb861 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING alignment: Alignment.center textDirection: ltr widthFactor: expand heightFactor: expand child: RenderPadding#848c3 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: offset=Offset(0.0, 0.0) constraints: MISSING size: MISSING padding: EdgeInsets.zero textDirection: ltr child: RenderConstrainedBox#18c35 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: offset=Offset(0.0, 0.0) constraints: MISSING size: MISSING additionalConstraints: BoxConstraints(0.0<=w<=Infinity, h=1.0) child 3: RenderConstrainedBox#61201 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: offset=Offset(0.0, 0.0); flex=null; fit=null constraints: MISSING size: MISSING additionalConstraints: BoxConstraints(w=430.0, 0.0<=h<=Infinity) child: RenderMouseRegion#90872 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING behavior: opaque listeners: enter, exit cursor: SystemMouseCursor(text) child: RenderTapRegion#245fa NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING behavior: deferToChild groupId: EditableText child: RenderIgnorePointer#c2f01 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE parentData: <none> constraints: MISSING size: MISSING ignoring: false ignoringSemantics: null child 4: RenderConstrainedBox#0eb83 NEEDS-LAYOUT NEEDS-PAINT parentData: offset=Offset(0.0, 0.0); flex=null; fit=null constraints: MISSING size: MISSING additionalConstraints: BoxConstraints(0.0<=w<=Infinity, h=18.6)
════════ 渲染库捕获的异常 ═════════════════════════════════
RenderBox 未完成布局: RenderFlex#83717 relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart': 断言失败: 第1972行第12位: 'hasSize'
用户的Widget build代码:
@override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: true, appBar: AppBar( backgroundColor: Colors.white, elevation: 0.0, title: Text( 'Chat', style: TextStyle( fontFamily: 'Chalet', fontWeight: FontWeight.w300, fontSize: widget.deviceWidth * 0.06), ), ), backgroundColor: whitePrimary, body: Column( children: [ Expanded( child: ListView.builder( itemCount: _messages.length, itemBuilder: (BuildContext context, int index) { return ListView( children: [Text(_messages[index])], ); }), ), const Divider(height: 1.0), _buildTextComposer(), SizedBox( height: widget.deviceHeight * 0.02, ) ], ), ); } Widget _buildTextComposer() { return SizedBox( width: widget.deviceWidth, child: TextField( autofocus: true, controller: _textFieldController, decoration: InputDecoration( border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, errorBorder: InputBorder.none, disabledBorder: InputBorder.none, filled: true, fillColor: whitePrimary, suffixIcon: IconButton( icon: const Icon(Icons.send_rounded, color: orangePrimary), onPressed: () { _sendMessage(_textFieldController.text); }, ), hintStyle: TextStyle(fontSize: widget.deviceWidth * 0.03), hintText: 'Write a message...', ), ), ); }
问题原因
崩溃的核心原因是嵌套的ListView没有约束高度:在ListView.builder的itemBuilder中返回了另一个ListView,而默认情况下ListView会试图占据无限高度,父级ListView无法确定子ListView的具体尺寸,导致布局系统无法完成计算,触发hasSize断言失败。
解决方案
有两种简单的修复方式:
方式一:直接移除嵌套的ListView
如果每条消息只是简单的文本,不需要子列表,直接返回Text组件即可:
itemBuilder: (BuildContext context, int index) { return Text(_messages[index]); }
方式二:给子ListView添加约束
如果确实需要嵌套列表(比如单条消息包含多个元素),给子ListView添加shrinkWrap: true(让列表根据内容自适应高度)和physics: NeverScrollableScrollPhysics()(禁用子列表滚动,避免和父列表滚动冲突):
itemBuilder: (BuildContext context, int index) { return ListView( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), children: [Text(_messages[index])], ); }
修复后效果
修改后,添加消息时布局系统能正确计算每个列表项的高度,不会再触发渲染断言错误,聊天界面可以正常展示和滚动。
内容的提问来源于stack exchange,提问作者Geo48
相关产品推荐
相关产品推荐

