Flutter布局(2):弹性布局(Flex、Expanded)

 


一、什么是弹性布局(Flex)

什么是弹性布局(Flex)? 弹性布局(Flex)是一种基于弹性盒子模型的布局方式,类似于 Web 开发中的 Flexbox。在 Flutter 中,Flex 组件是用于实现弹性布局的关键组件之一。Flex 布局是一种简洁且强大的方式,可用于构建水平或垂直方向的弹性布局。

Flex组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用RowColumn会方便一些,因为RowColumn都继承自Flex,参数基本相同,所以能使用Flex的地方基本上都可以使用RowColumnFlex本身功能是很强大的,它也可以和Expanded组件配合实现弹性布局。

Flex({
  ...
  required this.direction, // 弹性布局的方向, Row默认为水平方向,Column默认为垂直方向
  List<Widget> children = const <Widget>[],
})

二、什么情况下选择Flex比Row和Column更合适

使用场景: 在以下情况下,使用 Flex 布局是更合适的选择,而不使用 Row 和 Column:

  • 不确定子组件数量或尺寸:当子组件的数量或尺寸在运行时动态变化时,使用Flex布局可以更好地适应变化。通过设置弹性因子,可以根据需要自动调整子组件的尺寸比例。

  • 复杂的布局需求:如果需要更复杂的布局结构,涉及多个层次的嵌套和不同方向的排列,使用Flex布局可以提供更大的灵活性。可以通过嵌套多个Flex组件来实现更复杂的布局结构。

  • 自定义子组件尺寸和位置:使用Flex布局可以更灵活地控制子组件的尺寸和位置。通过设置弹性因子、对齐方式和主轴尺寸等属性,可以自定义子组件在布局中的行为。

举例说明: 假设我们有一个水平布局,其中包含两个子组件:一个固定宽度的按钮和一个可伸缩的文本框。当按钮的宽度固定时,我们希望文本框占据剩余的可用空间。

使用 Flex 布局可以轻松实现这个需求:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(title: const Text('Progress Indicators')),
          body: Flex(
            direction: Axis.horizontal,
            children: <Widget>[
              ElevatedButton(
                child: const Text('按钮'),
                onPressed: () {},
              ),
              const Expanded(
                child: TextField(
                  decoration: InputDecoration(
                    hintText: '请输入内容',
                  ),
                ),
              ),
            ],
          )),
    ),
  );
}

在这个例子中,我们使用了 Flex 组件和 Expanded 组件来构建弹性布局。ElevatedButton 是一个固定宽度的按钮,而 TextField 通过 Expanded 组件占据剩余的可用空间。效果图如下所示:

Flutter_layoutWidget_L.png


使用 Flex 更佳的场景

还有一些场景,使用 Flex 可能比 Row 和 Column 更佳。

  • 响应式布局:在响应式设计中,屏幕的尺寸和方向可能会发生变化。使用 Flex 布局和 Expanded 组件可以根据可用空间自动调整子组件的尺寸和位置,以适应不同的屏幕尺寸。
  • 列表或网格布局:当需要在列表或网格中显示可变数量的子组件时,使用 Flex 布局和 Expanded 组件可以自动调整子组件的尺寸和布局。例如,一个动态生成的图片网格,每个图片需要根据网格大小进行缩放和布局。
  • 混合布局:有时候我们可能需要在布局中组合使用水平和垂直排列的子组件。使用 Flex 布局和 Expanded 组件,可以创建复杂的混合布局,灵活地组合水平和垂直方向的子组件。
  • 自定义比例布局:有时候我们需要根据设计要求按比例调整子组件的尺寸。使用 Flex 布局和 Expanded 组件,可以设置不同的弹性因子(flex factor),以实现不同子组件之间的尺寸比例。
  • 动画效果: Flex 布局和 Expanded 组件可以与动画结合使用,创建动态变化的布局效果。通过动画来改变子组件的弹性因子、尺寸和位置,可以实现平滑的过渡和动态的布局变化。

三、Expanded组件

Flex 和 Expanded 的感情不得了,比亲儿子还亲。

用 Expanded 组件: Expanded 组件是 Flex 组件的一个特殊情况,它只能作为 Flex 的直接子组件。它可以按比例扩展 Flex 子组件所占用的空间。由于 Row 和 Column 都是 Flex 的子类,所以我们可以在它们内部使用 Expanded 来实现灵活的布局。

下面是一个可直接运行的代码示例,展示了如何使用 Flex、Row和 Expanded 组件构建一个水平方向的弹性布局:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flex布局示例'),
        ),
        body: Flex(
          direction: Axis.horizontal,
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Expanded(
              flex: 1,
              child: Container(
                color: Colors.red,
                height: 100,
              ),
            ),
            Expanded(
              flex: 2,
              child: Container(
                color: Colors.blue,
                height: 100,
              ),
            ),
            Expanded(
              flex: 1,
              child: Container(
                color: Colors.green,
                height: 100,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在这个例子中,我们创建了一个水平方向的弹性布局,其中使用了三个 Expanded 组件作为子组件。Expanded 组件的弹性因子(flex)分别为 1、2 和 1,使得子组件在可用空间中的比例为 1:2:1。效果图如下所示:

Flutter_layoutWidget_M.png


posted @   fengMisaka  阅读(227)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示