Flutter代码报错:RenderBox未布局及手势库无尺寸命中测试问题求助
问题分析与解决方案
错误根源
出现RenderBox was not laid out和Cannot hit test a render box with no size异常的核心原因:
- Expanded组件嵌套错误:Expanded必须直接作为Column/Row等弹性布局的子组件,不能被Padding、SizedBox这类容器包裹,否则无法参与父布局的空间分配,导致子组件无法获取正确尺寸。
- 冗余布局嵌套:外层的Center+固定高度Container,限制了Column的自适应能力,容易引发布局冲突。
修复后的代码
return Scaffold( backgroundColor: const Color(0xFF101d25), body: Column( children: [ const Padding( padding: EdgeInsets.only(top: 110), child: Text( 'Welcome to WhatsApp', style: TextStyle( fontSize: 35, color: Colors.white, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), ), // 调整Expanded与Padding的嵌套顺序 Expanded( child: Padding( padding: const EdgeInsets.symmetric(vertical: 70), child: SizedBox( child: Image.asset( 'images/image_whatsapp.jpg', height: 260, width: 260, ), ), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 22), child: RichText( textAlign: TextAlign.center, text: TextSpan(children: [ const TextSpan( text: 'Read our ', style: TextStyle(color: Colors.white, fontSize: 16)), TextSpan( text: 'Privacy Policy', style: const TextStyle(color: Colors.blue, fontSize: 16), recognizer: TapGestureRecognizer() ..onTap = () { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text('Privacy Policy'), content: const Text( 'This is a test to show a Alert dialog...'), actions: <Widget>[ TextButton( child: const Text('Agree'), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( child: const Text('Disagree'), onPressed: () { Navigator.of(context).pop(); }, ) ], ); }); }), const TextSpan( text: ' Tap "Agree and continue" to accept the ', style: TextStyle(color: Colors.white, fontSize: 16), ), TextSpan( text: 'Terms of Service', style: const TextStyle(color: Colors.blue, fontSize: 16), recognizer: TapGestureRecognizer() ..onTap = () { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text('Terms of Service'), content: const Text( 'This is a test to show a Alert dialog...'), actions: <Widget>[ TextButton( child: const Text('Agree'), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( child: const Text('Disagree'), onPressed: () { Navigator.of(context).pop(); }, ) ], ); }); }), const TextSpan( text: '.', style: TextStyle(color: Colors.white, fontSize: 16), ), ]), ), ), const SizedBox(height: 20), SizedBox( height: 50, width: 480, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 50), child: ElevatedButton( onPressed: () { _dialogBuilder(context); }, style: ElevatedButton.styleFrom( shape: BeveledRectangleBorder( borderRadius: BorderRadius.circular(2)), backgroundColor: const Color(0xFF0ca886)), child: const Padding( padding: EdgeInsets.symmetric(vertical: 12), child: Text( 'AGREE AND CONTINUE', style: TextStyle( color: Color(0xFF121a21), fontSize: 16), ), )), ), ), // 移除多余的SizedBox const Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Text( "From", style: TextStyle(color: Colors.white), textAlign: TextAlign.center, ), Text("FACEBOOK", style: TextStyle( letterSpacing: 3, color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16, ), textAlign: TextAlign.center) ], ), ), ], ), );
关键修改点
- 调整Expanded嵌套关系:将第一个Expanded从Padding的子节点改为父节点,确保Expanded直接参与Column的空间分配。
- 移除冗余嵌套:删除外层Center和固定高度Container,让Column直接作为Scaffold的body,利用弹性布局自适应屏幕。
- 修正拼写错误:将
Privicy Police改为规范的Privacy Policy。 - 清理多余组件:移除底部Expanded外层的无用SizedBox,简化布局层级。
内容的提问来源于stack exchange,提问作者Thiago Ferreira
相关产品推荐
相关产品推荐

