Flutter布局(1):线性布局(Row、Column)

 


所谓线性布局,即指沿水平或垂直方向排列子组件。Flutter 中通过RowColumn来实现线性布局。

主轴和纵轴

对于线性布局,有主轴和纵轴之分,如果布局是沿水平方向,那么主轴就是指水平方向,而纵轴即垂直方向;如果布局沿垂直方向,那么主轴就是指垂直方向,而纵轴就是水平方向。

一、Row组件

1.1 Row介绍

在 Flutter 中,Row是一个水平布局的小部件,用于将子控件沿着水平轴排列。它非常适合用来创建行式布局,如表单输入、按钮组、标签栏等。从源码中查看 Row的属性:

Row({
  Key key,
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主轴对齐方式
  MainAxisSize mainAxisSize = MainAxisSize.max, // 水平方向尽可能大
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 交叉轴对齐方式
  TextDirection textDirection, // 水平方向子widget的布局顺序(默认为系统当前Locale环境的文本方向(如中文、英语都是从左往右,而阿拉伯语是从右往左))
  VerticalDirection verticalDirection = VerticalDirection.down, // 表示Row纵轴(垂直)的对齐方向
  TextBaseline textBaseline, // 如果上面是baseline对齐方式,那么选择什么模式(有两种可选)
  List<Widget> children = const <Widget>[],
})

1.2 基础用法

Row最基本的用法是将多个控件水平排列:

Row(
  children: <Widget>[
    Container(width: 50.0, height: 50.0, color: Colors.red),
    Container(width: 50.0, height: 50.0, color: Colors.blue),
    // ... 更多的控件
  ],
)

1.3 主轴对齐

RowmainAxisAlignment属性用于控制子控件在主轴(水平轴)上的对齐方式,其是一个枚举类型,代码如下:

enum MainAxisAlignment {
  // 将子控件放在主轴的开始位置
  start,  
  
  // 将子控件放在主轴的结束位置
  end,
  
  // 将子控件放在主轴的中间位置
  center,
  
  // 将主轴空白位置进行均分,排列子元素,手尾没有空隙
  spaceBetween,
  
  // 将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
  spaceAround,
  
  // 将主轴空白区域均分,使各个子控件间距相等
  spaceEvenly,
}

1.4 交叉轴对齐

RowcrossAxisAlignment属性用于控制子控件在交叉轴(垂直轴)上的对齐方式,其是一个枚举类型,代码如下:

enum CrossAxisAlignment {
  // 将子控件放在交叉轴的起始位置
  start,

  // 将子控件放在交叉轴的结束位置
  end,

  // 将子控件放在交叉轴的中间位置
  center,

  // 使子控件填满交叉轴
  stretch,

  // 将子控件放在交叉轴的上,并且与基线相匹配(不常用)
  baseline,
}

1.5 间距和边距

RowmainAxisSize属性决定了Row的大小是否应该占据所有可用空间:

Row(
  mainAxisSize: MainAxisSize.max,
  // ... 子控件
)
  • 默认是MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度;
  • MainAxisSize.min表示尽可能少的占用水平空间,当子widgets没有占满水平剩余空间,则Row的实际宽度等于所有子widgets占用的的水平空间;

通过padding属性,可以为Row添加内边距:

Row(
  padding: EdgeInsets.all(8.0),
  // ... 子控件
)

1.6 子控件大小调整

使用flex属性来设置子控件在Row中的弹性比例:

Row(
  children: <Widget>[
    Expanded(
      flex: 1,
      child: Container(color: Colors.red),
    ),
    Expanded(
      flex: 2,
      child: Container(color: Colors.blue),
    ),
  ],
)

1.7 实例

下面是一个使用Row创建水平布局的实例:

// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyHomeBody(),
      ),
    );
  }
}

class MyHomeBody extends StatelessWidget {
  const MyHomeBody({super.key});
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 500,
      margin: EdgeInsets.all(10),
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.black,
          width: 1,
        ),
      ),
    
      child:Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 主轴对齐方式:均匀分布
        crossAxisAlignment: CrossAxisAlignment.center, // 交叉轴对齐方式:居中对齐
        children: <Widget>[
          Container(color: Colors.red, width: 60, height: 60),
          Container(color: Colors.blue, width: 80, height: 80),
          Container(color: Colors.green, width: 70, height: 70),
          Container(color: Colors.orange, width: 100, height: 100),
        ],
      )
    );
  }
}

效果图如下:

Flutter_layout_M.png


二、Column组件

2.1 Column介绍

在 Flutter 中,Column是一个垂直布局的小部件,用于将子控件沿着垂直轴排列。ColumnRow相对,Row是水平布局,而Column则是垂直布局。它非常适合用来创建列式布局,如表单、列表项、导航栏等。从源码中查看Column的属性:

Column({
  Key key,
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
  MainAxisSize mainAxisSize = MainAxisSize.max,
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
  TextDirection textDirection,
  VerticalDirection verticalDirection = VerticalDirection.down,
  TextBaseline textBaseline,
  List<Widget> children = const <Widget>[],
})

2.2 基础用法

Column最基本的用法是将多个控件垂直排列:

Column(
  children: <Widget>[
    Container(height: 50.0, color: Colors.red),
    Container(height: 50.0, color: Colors.blue),
    // ... 更多的控件
  ],
)

属性基本都和Row的一致,所以下面就不赘述了,直接看实例。


2.3 实例

我们直接将Row的代码中Row改为Column,查看代码运行效果:

// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';

main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyHomeBody(),
      ),
    );
  }
}

class MyHomeBody extends StatelessWidget {
  const MyHomeBody({super.key});
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 500,
      margin: EdgeInsets.all(10),
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.black,
          width: 1,
        ),
      ),
    
      child:Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 主轴对齐方式:均匀分布
        crossAxisAlignment: CrossAxisAlignment.center, // 交叉轴对齐方式:居中对齐
        children: <Widget>[
          Container(color: Colors.red, width: 60, height: 60),
          Container(color: Colors.blue, width: 80, height: 80),
          Container(color: Colors.green, width: 70, height: 70),
          Container(color: Colors.orange, width: 100, height: 100),
        ],
      )
    );
  }
}

效果图如下:

Flutter_layout_O.png


posted @   fengMisaka  阅读(585)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇
点击右上角即可分享
微信分享提示