如何使ExpansionPanelList拥有自然宽度并适配Drawer内滚动?
组件结构如下:
Drawer SingleChildScrollView Wrap (vertical) Center Column (mainAxisSize: min) ExpansionPanelList
通过Widget Inspector可知,Drawer默认宽度为304。
遇到的错误断言:
The following assertion was thrown during performLayout():
RenderListBody must have a bounded constraint for its cross axis.RenderListBody forces its children to expand to fit the RenderListBody's container, so it must be placed in a parent that constrains the cross axis to a finite dimension.
If you are attempting to nest a RenderListBody with one direction inside one of another direction, you will want to wrap the inner one inside a box that fixes the dimension in that direction, for example, a RenderIntrinsicWidth or RenderIntrinsicHeight object. This is relatively expensive, however.
The relevant error-causing widget was
ExpansionPanelList
目前用SizedBox(width: 200)包裹能解决错误,但不想固定宽度——希望宽度匹配父组件,而且固定宽度会导致面板展开时可能溢出报错。
解决方案
1. 用IntrinsicWidth适配自然宽度
按照错误提示的思路,用IntrinsicWidth包裹ExpansionPanelList,它会让子组件根据自身内容计算自然宽度,同时给RenderListBody提供明确的交叉轴约束:
IntrinsicWidth( child: ExpansionPanelList( // 你的面板配置 children: [ // 具体面板项 ], ), )
说明:IntrinsicWidth会触发两次布局,性能开销略高,但Drawer这种场景下基本没影响。
2. 用LayoutBuilder+ConstrainedBox绑定父组件宽度
如果不想用IntrinsicWidth,可通过LayoutBuilder获取父组件的可用宽度,再用ConstrainedBox限制ExpansionPanelList的最大宽度,既匹配父组件宽度,又能避免溢出:
LayoutBuilder( builder: (context, constraints) { return ConstrainedBox( constraints: BoxConstraints(maxWidth: constraints.maxWidth), child: ExpansionPanelList( children: [ // 具体面板项 ], ), ); }, )
3. 简化外层布局结构
原布局里的Wrap(vertical)+Center+Column(mainAxisSize: min)导致宽度约束模糊,直接简化布局:
把Wrap换成Column,去掉多余的Center,让ExpansionPanelList直接继承Drawer的宽度约束:
Drawer( child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ ExpansionPanelList( // 你的面板配置 children: [/*...*/], ), // 其他子组件 ], ), ), )
这样ExpansionPanelList会自动适配Drawer宽度,内容超出时SingleChildScrollView也能正常滚动。
内容的提问来源于stack exchange,提问作者eastwater

