在布局问题上,Flutter 可能会表现得相当不宽容。我将带您了解其中最令人头疼的那些问题以及如何真正解决它们。

Flutter 常见的布局异常错误

布局异常错误

视频

前言

原文 Flutter 常见的布局异常错误

在布局问题上,Flutter 可能会表现得相当不宽容。我将带您了解其中最令人头疼的那些问题以及如何真正解决它们。

RenderFlex 溢出错误

刚开始使用 Flutter 时,这个异常总会让人抓狂。当你在 RowColumn 中放置了太多内容时,就会突然出现——到处都是黄黑相间的条纹。

通常导致此问题的原因如下:

          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)),
        ],
      ),

Flexible

有时候,如果你确实需要水平滚动,只需将整个 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),
              ],
            ),
          ),

SingleChildScrollView

键盘导致底部溢出

当键盘弹出且屏幕上内容过多时,就会发生这种情况。

问题代码:

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')),
          ],
        ),
      ),
    );
  }
}

SingleChildScrollView

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')),
                ],
              ),
            ),
          ],
        ),
      ),
    );

ListView

或者为其指定一个固定高度:

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

Expanded 只能在像 RowColumnFlex 这样的 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'),
            ),
          ],
        ),
      ),
      ),
    );

Positioned

希望以上内容能帮到您。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


猫哥 APP

flutter 学习路径


© 猫哥 ducafecat.com

end