logo头像

aferica

Flutter学习(二):常用布局控件介绍

本文于1682天之前发表,文中内容可能已经过时。

在上一篇博文中,我简单的介绍了一些Flutter的知识和优势以及环境配置问题,在本篇博文中,我主要介绍一下常用到的几种Flutter常用布局控件和使用方法。
20190530001154.png
首先,我们先来一张Flutter基本空间继承关系图:
20190531165341.png

Container

本段介绍来自Flutter 布局(一)- Container详解
Container是Flutter最常使用的布局控件之一

使用场景

  • 需要设置间隔(这种情况下,如果只是单纯的间隔,也可以通过Padding来实现);
  • 需要设置背景色;
  • 需要设置圆角或者边框的时候(ClipRRect也可以实现圆角效果);
  • 需要对齐(Align也可以实现);
  • 需要设置背景图片的时候(也可以使用Stack实现)

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
})

属性解析

  • key:Container唯一标识符,用于查找更新。
  • alignment:控制child的对齐方式,如果container或者container父节点尺寸大于child的尺寸,这个属性设置会起作用,有很多种对齐方式。
  • padding:decoration内部的空白区域,如果有child的话,child位于padding内部。padding与margin的不同之处在于,padding是包含在content内,而margin则是外部边界,设置点击事件的话,padding区域会响应,而margin区域不会响应。
  • color:用来设置container背景色,如果foregroundDecoration设置的话,可能会遮盖color效果。
  • decoration:绘制在child后面的装饰,设置了decoration的话,就不能设置color属性,否则会报错,此时应该在decoration中进行颜色的设置。
  • foregroundDecoration:绘制在child前面的装饰。
  • width:container的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局。
  • height:container的高度,设置为double.infinity可以强制在高度上撑满。
  • constraints:添加到child上额外的约束条件。
  • margin:围绕在decoration和child之外的空白区域,不属于内容区域。
  • transform:设置container的变换矩阵,类型为Matrix4。
  • child:container中的内容widget。

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
new Container(
constraints: new BoxConstraints.expand(
height:Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
decoration: new BoxDecoration(
border: new Border.all(width: 2.0, color: Colors.red),
color: Colors.grey,
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
image: new DecorationImage(
image: new NetworkImage('http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
),
),
padding: const EdgeInsets.all(8.0),
alignment: Alignment.center,
child: new Text('Hello World',
style: Theme.of(context).textTheme.display1.copyWith(color: Colors.black)),
transform: new Matrix4.rotationZ(0.3),
)

Row和Column

RowColumn两个基本相同,只有一个是横向,一个是纵向布局的区别,所以我们以Row为例来介绍说明。

使用场景

  • 需要横向(纵向)排列,如标签展示
  • 网格布局(GridView也可以实现)

构造函数

1
2
3
4
5
6
7
8
9
10
Row({
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>[],
})

属性解析

  • key:Flutter控件(Widget)唯一标识符,用于查找更新。
  • mainAxisAlignment:子元素对齐方式,MainAxisAlignment对象,类似于css中的justify-contentalign-content

    有六种对齐方式:
    start开始(左侧或顶部)对齐
    end开始(右侧或底部)对齐
    center居中对齐
    spaceBetween子元素之间留有空白,但第一个元素之前和最后一个元素之后不留空白,类似于css中space-between
    de76ada5cdf9305499b1b02eb32a934.jpg
    spaceAround子元素之间留有空白,第一个元素之前和最后一个元素之后留一半的空白,类似于css中space-around
    d0e861bfffb9e1b051c9c08c94e35a4.jpg
    spaceEvenly子元素之间留有空白,第一个元素之前和最后一个元素之后留相等的空白,类似于css中space-around
    67281de4285163df268f40f822e0f3e.jpg

  • mainAxisSize:主方向大小,有min和max两个值可选
  • crossAxisAlignment:子元素在交叉轴方向的对齐方式
  • verticalDirection:定义了子元素摆放顺序,默认是down,即从左到右(从上到下),可选还有up,即从右到左(从下到上)

简单示例

上面三图中的追书人数和读者留存率行实现:

1
2
3
4
5
6
7
8
9
10
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max, // 默认即为max,可不写
children: <Widget>[
Text('追书人数:', style: TextStyle(fontSize: 12.0,height: 1.5),),
Text(latelyFollower, style: TextStyle(fontSize: 13.0, color: Colors.pink,height: 1.5),),
Text('读者留存率:', style: TextStyle(fontSize: 12.0,height: 1.5)),
Text(retentionRatio, style: TextStyle(fontSize: 13.0, color: Colors.pink,height: 1.5),)
],
)

Scaffold

Scaffold可以说的上是Flutter中基本的页面布局

使用场景

  • 几乎所有页面都可以使用

    构造函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Scaffold({
    Key key,
    this.appBar,
    this.body,
    this.floatingActionButton,
    this.floatingActionButtonLocation,
    this.floatingActionButtonAnimator,
    this.persistentFooterButtons,
    this.drawer,
    this.endDrawer,
    this.bottomNavigationBar,
    this.bottomSheet,
    this.backgroundColor,
    this.resizeToAvoidBottomPadding,
    this.resizeToAvoidBottomInset,
    this.primary = true,
    this.drawerDragStartBehavior = DragStartBehavior.start,
    this.extendBody = false,
    })

属性解析

  • key:Flutter控件(Widget)唯一标识符,用于查找更新。
  • appBar: 标题栏,详见后续介绍
  • body:页面内容
  • floatingActionButton:固定页面之上的悬浮按钮,诸如返回顶部、新增按钮都推荐使用
  • floatingActionButtonLocation:顾名思义,悬浮按钮位置
  • floatingActionButtonAnimator:
  • persistentFooterButtons:固定在页面底部,例如微信、QQ底部的聊天框
  • drawer:左侧抽屉
  • endDrawer:右侧抽屉,注意:如果在标题栏AppBar中设置有actions,右侧添加的操作按钮会将抽屉的默认打开按钮覆盖,需要自己实现打开抽屉
  • bottomNavigationBar:App常用底部导航栏
  • backgroundColor:内容的背景颜色,默认使用的是 ThemeData.scaffoldBackgroundColor 的值
  • resizeToAvoidBottomPadding:控制界面内容 body 是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true
微信打赏

你的赞赏是对我最大的鼓励