Flutter中ExpansionTile展开后内部ListView.builder不显示问题
Flutter ExpansionTile 内嵌 ListView.builder 不显示内容问题
我通过ListView.builder生成一组ExpansionTile,每个ExpansionTile展开后需显示另一ListView.builder生成的子项列表。当前问题:ExpansionTile已处于展开状态(显示展开样式),但内部的ListView.builder无法显示内容。
组件结构
FutureBuilder -> 数据未加载时返回 CircularLoading Indicator -> 数据加载完成后返回第一个 ListView.builder,生成包含 ExpansionTiles 的列表 -> ExpansionTile children: FutureBuilder(问题区域) -> 数据未加载时返回 CircularLoading Indicator -> 数据加载完成后返回第二个 ListView.builder,生成子项列表
问题代码片段
ExpansionTile( ...// 样式属性 onExpansionChanged: (bool expanding) => { generateDataFunction().then((_){ setState((){ }); } }, children: <Widget>[ FutureBuilder( future: dataFuture, builder: (context, snapshot) { if(snapshot.connectionState != ConnectionState.done){ return Center(child: CircularProgressIndicator()); } else{ return ListView.builder( // <------------- 问题所在 shrinkWrap: true, // 保持true,因为ListView需要有限高 itemCount: data.length controller: dataListScrollController, itemBuilder: (BuildContext context, int index){ return ListTile( ...// 传入所需数据设置title等 ); } ); } } ), ]
补充信息
- 将内部
ListView.builder替换为带children的普通List并添加ListTile,可正常显示,说明数据和FutureBuilder本身无问题。 - 尝试用Container强制设置尺寸,无效。
ListTile 代码
Container( color: Colors.grey, child: ListTile( title: Text(widget.title /* 带样式 */) isThreeLine: true, trailing: const SizedBox(), contentPadding: EdgeInsets.only(left: 30) subtitle: RichText(/* TextSpans... */) ) )
解决方法
1. 调整滚动物理属性
嵌套的ListView若允许滚动,可能与外部滚动组件冲突,导致内容无法渲染。添加NeverScrollableScrollPhysics():
ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), // 添加该行 itemCount: data.length, controller: dataListScrollController, itemBuilder: (context, index) { // ... ListTile 代码 } )
2. 验证数据长度
确认data列表非空,可在返回ListView前打印数据长度:
print("数据长度: ${data.length}"); return ListView.builder(...);
3. 修复语法错误
代码中itemCount: data.length后缺少逗号,这会导致编译异常,补上逗号:
itemCount: data.length, // 补上逗号 controller: dataListScrollController,
4. 替换为Column+SingleChildScrollView(备选)
若上述方法无效,可改用Column结合SingleChildScrollView替代内部ListView(注意子项过多时的性能问题):
return SingleChildScrollView( child: Column( children: data.map((item) { return ListTile(/* 对应item的内容 */); }).toList(), ), );
内容的提问来源于stack exchange,提问作者TheCoolest2
相关产品推荐
相关产品推荐

