PHP开源Hub
致力于开发者的提升

Flutter 基础(十)布局 Widget 快速入门

Flutter基础(十)布局Widget快速入门

前言

Flutter 的布局在此前的文章多多少少用过,但是没有具体讲过,Flutter 的布局实际上也由 Widget 来控制的,在 Flutter 官网上并没有对布局 Widget 进行分类,这里将布局 Widget 根据子元素排列方式分为以下几种:

  • 线性布局 Widget
  • 流式布局 Widget
  • 层式布局 Widget
  • 弹性布局 Widget

下面分别介绍这几种布局 Widget。

1. 线性布局 Widget

线性布局类似于 Android 中的 LinearLayout,可以垂直也可以水平排列,Flutter 的线性布局有两个:

  • Row:水平方向的线性布局。
  • Column:垂直方向的线性布局。

Row 和 Column 的使用方法类似,举个 Row 的例子,Column 自然而然也就会了。

import 'package:flutter/material.dart';

void main() => runApp(RowWidget());

class RowWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter",
      home: Scaffold(
        appBar: AppBar(
          title: Text("Row示例"),
        ),
        body: Padding(
          padding: EdgeInsets.all(40.0),
          child: Row(
            children: <Widget>[
              Text("Android进阶之光"),
              Text("Android进阶解密"),
            ],
          ),
        ),
      ),
    );
  }
}

效果如下图所示。

ZKvSQP.png

2. 流式布局 Widget

流式布局就是把超出屏幕显示范围的控件自动换行,在 Android 中并没有现成的流式布局控件,都是开发人员自己封装的,比如鸿洋封装的 FlowLayout。Flutter 中提供了 Wrap 来实现流式布局。

import 'package:flutter/material.dart';
void main() => runApp(ChipWidget());

class ChipWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter",
      home: Scaffold(
        appBar: AppBar(
          title: Text("流式布局示例"),
        ),
        body: Padding(
          padding: EdgeInsets.all(20.0),
          child: Wrap(
            direction: Axis.horizontal, //主轴的方向
            spacing: 8.0, // 主轴方向的间距
            runSpacing: 12.0, // 交叉轴方向的间距
            children: <Widget>[
              Chip(//1
                avatar: CircleAvatar(
                    backgroundColor: Colors.blue, child: Text('1')),
                label: Text('Android进阶之光'),
              ),
              Chip(
                avatar: CircleAvatar(
                    backgroundColor: Colors.blue, child: Text('2')),
                label: Text('Android进阶解密'),
              ),
              Chip(
                avatar: CircleAvatar(
                    backgroundColor: Colors.blue, child: Text('3')),
                label: Text('Android进阶?'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注释 1 处的 Chip 意为碎片,实际上是一个标签 Widget,这个例子中定义了三个标签来体现流式布局。
Wrap 有很多属性,它的构造函数如下:

Wrap({
      Key key,
      this.direction = Axis.horizontal, //1
      this.alignment = WrapAlignment.start,//2
      this.spacing = 0.0,
      this.runAlignment = WrapAlignment.start,
      this.runSpacing = 0.0,
      this.crossAxisAlignment = WrapCrossAlignment.start,
      this.textDirection,
      this.verticalDirection = VerticalDirection.down,
      List<Widget> children = const <Widget>[],
}) : super(key: key, children: children);

注释 1 处的 direction 属性,它用于设定主轴的方向(子 Widget 排列的方向),默认值为 Axis.horizontal,部分属性见下表:

参数名称 参数类型 含义
direction Axis 主轴的方向
alignment WrapAlignment 子 Widget 在主轴上的对齐方式
runAlignment WrapAlignment 每行或每列的对齐方式
runSpacing double 每行或每列之间的间距
crossAxisAlignment WrapCrossAlignment 子 Widget 在交叉轴上的对齐方式
textDirection TextDirection 子 Widget 在主轴方向上的布局顺序
verticalDirection VerticalDirection 子 Widget 在交叉轴方向上的布局顺序

运行后的效果如下图所示。

ZlZfWq.png

3. 层式布局 Widget

层式布局类似于 Android 的 FrameLayout,在 Flutter 可以通过 Stack 来实现层式布局,其子 Widget 会按照添加顺序确定显示层级,后面添加的会覆盖在前面添加的 Widget 上面。
为了确定子 Widget 到父容器四个角的位置,Stack 将子 Widget 分为两类:

  • positioned:Positioned 嵌套的子 Widget,Positioned 可以控制子 Widget 到父容器四个边的距离。
  • non-positioned :没有用 Positioned 嵌套起来的子 Widget,使用 Stack 的 alignment 属性来控制自身在父容器里的位置。
import 'package:flutter/material.dart';
void main() => runApp(StackWidget());

class StackWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter",
      home: Scaffold(
        appBar: AppBar(
          title: Text("层式布局示例"),
        ),
        body: Stack(
          fit: StackFit.expand,
          children: <Widget>[
            Positioned(
              left: 90.0,
              top: 120.0,
              child: Image.asset(
                "images/decode.png",
                width: 200.0,
                fit: BoxFit.cover,
              ),
            ),
            Container(
              child: Text('Android进阶三部曲第二部',
                  style: TextStyle(
                      color: Colors.lightBlue, fontSize: 20.0)),
              height: 50.0,
              width: 100.0,
              alignment: Alignment.center,
            )
          ],
        ),
      ),
    );
  }
}

上面的代码中,Stack 分为两个部分,一个是 Positioned Widget,用于显示一个图片,一个是 non-positioned Widget,嵌套在 Container 中,用于显示一行文字。效果如下图所示。

ZKjxzt.png

4. 弹性布局 Widget

Flutter 中的弹性布局是 Flex,类似于 Android 中的 FlexboxLayout。为了避免子 Widget 在 Flex、Row、Column 中超界,可以使用 Flexible 和 Expanded,它们可以让 Flex、Row、Column 的子 Widget 具有弹性能力,下面以 Flex 和 Expanded 搭配使用作为例子。

import 'package:flutter/material.dart';
void main() => runApp(FlexWidget());

class FlexWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter",
      home: Scaffold(
        appBar: AppBar(
          title: Text("弹性布局示例"),
        ),
        body: Flex(
          direction: Axis.horizontal,//1
          children: <Widget>[
            Expanded(
              flex: 1,
              child: Container(
                height: 60.0,
                width: 30.0,
                color: Colors.red,
              ),
            ),
            Expanded(
              flex: 3,
              child: Container(
                height: 60.0,
                width: 30.0,
                color: Colors.yellow,
              ),
            ),
            Expanded(
              flex: 1,
              child: Container(
                height: 60.0,
                width: 30.0,
                color: Colors.blue,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

注释 1 处的 direction 属性,用于设置主轴的方向,这是必须要设置的。Flex 的子 Widget 是三个 Expanded,每个 Expanded 负责显示一个矩形色块,用 flex 来设置弹性系数,三个矩形色块的比例为 1:3:1,效果如下图所示。

ZKjjJA.png

总结

本文介绍了 Flutter 中布局 Widget 分类,实际上对于每个布局分类都可以写一篇文章,这里都做了简化,带领大家快速入门。如果你想了解更多,可以查看文档或者直接查看各种 Widget 的源码。

赞(0) 打赏
未经允许不得转载PHP开源Hub » Flutter 基础(十)布局 Widget 快速入门

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

PHP开源Hub-致力于互联网开发者的成长

技术群聊软文发表

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏