Flutter 常见的布局异常错误
视频
前言
在布局问题上,Flutter 可能会表现得相当不宽容。我将带您了解其中最令人头疼的那些问题以及如何真正解决它们。
RenderFlex 溢出错误
刚开始使用 Flutter 时,这个异常总会让人抓狂。当你在 Row
或 Column
中放置了太多内容时,就会突然出现——到处都是黄黑相间的条纹。
通常导致此问题的原因如下:
Row(
children: [
Container(width: 200, height: 100, color: Colors.red),
Container(width: 200, height: 100, color: Colors.blue),
Container(width: 200, height: 100, color: Colors.green),
],
),
修复方法通常是将内容包裹在 Flexible
或 Expanded
中:
Row(
children: [
Flexible(child: Container(width: 200, height: 100, color: Colors.red)),
Flexible(child: Container(width: 200, height: 100, color: Colors.blue)),
Flexible(child: Container(width: 200, height: 100, color: Colors.green)),
],
),
有时候,如果你确实需要水平滚动,只需将整个 Row
包裹在 SingleChildScrollView
中即可。
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(width: 200, height: 100, color: Colors.red),
Container(width: 200, height: 100, color: Colors.blue),
Container(width: 200, height: 100, color: Colors.green),
],
),
),
键盘导致底部溢出
当键盘弹出且屏幕上内容过多时,就会发生这种情况。
问题代码:
return Scaffold(
body: Column(
children: [
Container(height: 200, color: Colors.red),
Container(height: 200, color: Colors.blue),
Container(height: 200, color: Colors.green),
TextField(decoration: InputDecoration(hintText: 'Type something')),
],
),
);
解决方法取决于你的需求。通常情况下可以使用 SingleChildScrollView
:
class BottomOverflowFixedExample extends GetView {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Container(height: 300, color: Colors.red),
Container(height: 400, color: Colors.blue),
Container(height: 300, color: Colors.green),
TextField(decoration: InputDecoration(hintText: 'Type something')),
],
),
),
);
}
}
ListView 中的高度未受限制
这个令人困惑的地方在于,ListView
默认情况下在 Column
中不起作用。你会得到一个关于无界约束条件的晦涩错误。
问题:
return Scaffold(
body: Column(
children: [
Text('Header'),
ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
),
],
),
);
突然,屏幕上什么都没有了:
调试控制台中的异常信息:
将任何可滚动的小部件放在另一个可滚动小部件内部时,我们将会遇到类似的异常。
修复方法:我们需要将 ListView
包裹在 Expanded
中:
SafeArea(
child: Scaffold(
body: Column(
children: [
Text('Header'),
Expanded(
child: ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
),
),
],
),
),
);
或者为其指定一个固定高度:
return SafeArea(
child: Scaffold(
body: Column(
children: [
Text('Header'),
SizedBox(
height: 200, //here
child: ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
),
),
],
),
),
);
ParentDataWidget 使用不当
当你在错误的位置使用了 Expanded
时,就会出现这个错误。这就像把一个方形的插头插入一个圆形的插孔。
错误用法:
class ParentDataWrongExample extends GetView {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Expanded( // This doesn't make sense here
child: Text('Exception will be thrown'),
),
),
);
}
}
Expanded
只能在像 Row
、Column
或 Flex
这样的 Flex 组件内部使用:
return SafeArea(
child: Scaffold(
body: Container(
child: Column(
children: [
Expanded( // This doesn't make sense here
child: Text('Exception will be thrown'),
),
],
),
),
),
);
将 Positioned
放在 Stack
外部时,也会遇到类似的异常:
return SafeArea(
child: Scaffold(
body: Container(
child: Column(
children: [
Positioned( // This doesn't make sense here
child: Text('Exception will be thrown'),
),
],
),
),
),
);
希望以上内容能帮到您。
感谢阅读本文
如果有什么建议,请在评论中让我知道。我很乐意改进。
猫哥 APP
flutter 学习路径
- Flutter 优秀插件推荐
- Flutter 基础篇1 - Dart 语言学习
- Flutter 基础篇2 - 快速上手
- Flutter 实战1 - Getx Woo 电商APP
- Flutter 实战2 - 上架指南 Apple Store、Google Play
- Flutter 基础篇3 - 仿微信朋友圈
- Flutter 实战3 - 腾讯即时通讯 第一篇
- Flutter 实战4 - 腾讯即时通讯 第二篇
© 猫哥 ducafecat.com
end