Flutter中Card内Column添加ListTile出现RenderBox未布局错误求助
解决Flutter中RenderBox未布局错误的方案
问题核心
横向ListView的子组件(Card)没有明确的宽度约束,导致内部Column中的ListTile无法获取有效布局空间,触发"RenderBox was not laid out"错误。即使使用Expanded,由于父级无宽度限制,Expanded也无法正确分配空间。
修复方案
给Card添加明确的宽度约束,比如用SizedBox包裹Card并指定宽度,让内部组件基于该宽度完成布局。同时优化Column的主轴尺寸,避免不必要的空间扩展。
修改后的代码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePaState(); } class _HomePaState extends State<HomePage> { @override Widget build(BuildContext context) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values); return Scaffold( backgroundColor: Color(0xFFEDF5FC), body: Container( width: double.infinity, height: double.infinity, child: SingleChildScrollView( child: Padding( padding: EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Welcome, John", style: TextStyle(fontSize: 20, color: Color(0xFF8FBBDE)), ), Icon(Icons.notifications) ], ), Text( "Do you want to find a hotel?", style: TextStyle(fontSize: 12, color: Color(0xFFC2C9CF)), ), SizedBox( height: 10, ), Padding( padding: EdgeInsets.all(5), child: Row( children: [ Expanded( child: Container( child: TextFormField( decoration: InputDecoration(border: InputBorder.none), ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Color(0xFFE1EBF8)), )), SizedBox( width: 10, ), ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( child: Center( child: Icon( Icons.search, color: Colors.white, ), ), width: 50, height: 40, color: Color(0xFF5597CB), ), ) ], ), ), SizedBox( height: 10, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Popular Hotels", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), Text( "View all", style: TextStyle(fontSize: 12, color: Color(0xFFC2C9CF)), ) ], ), SizedBox( height: 300, child: ListView( scrollDirection: Axis.horizontal, children: [ // 给Card添加固定宽度约束 SizedBox( width: 220, // 可根据需求调整宽度 child: Card( margin: EdgeInsets.all(5), child: Column( mainAxisSize: MainAxisSize.min, // 让Column仅包裹子组件 children: [ ClipRRect( borderRadius: BorderRadius.circular(5), child: Image.asset( "assets/images/hotels/hotel2.jpg", height: 200, width: double.infinity, // 图片铺满Card宽度 fit: BoxFit.cover, ), ), ListTile(title: Text("mountain hotel")), ], ), ), ), ], ), ) ], ), ), ), ), ); } }
关键修改说明
- 用
SizedBox包裹Card并指定宽度,为内部组件提供明确的布局边界 - 给
Image设置width: double.infinity,让图片铺满Card宽度,保证布局一致性 - 给
Column添加mainAxisSize: MainAxisSize.min,避免Column占用多余垂直空间
内容的提问来源于stack exchange,提问作者Mokhtar Ghaleb
相关产品推荐
相关产品推荐

