Flutter 中布局方式的简单介绍

更多信息请查看flutter layout

Layouts

Sigle-child layout widgets

Container:

一个方便的小控件,结合常见的绘画,定位和尺寸的小控件。
属性包括:

  • alignment: 对齐方式
  • padding: 内边距
  • color: 颜色
  • decoration: 装饰
  • foregroundDecoration: 前置装饰
  • width: 宽度
  • height: 高度
  • constraints: 约束
  • margin: 外边距
  • transform: 转场方式
  • child: 子控件

示例:

new Container( constraints: new BoxConstraints.expand( height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0, ), padding: const EdgeInsets.all(8.0), color: Colors.teal.shade700, alignment: Alignment.center, child: new Text('Hello World', style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white)), foregroundDecoration: new BoxDecoration( image: new DecorationImage( image: new NetworkImage('https://www.example.com/images/frame.png'), centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0), ), ), transform: new Matrix4.rotationZ(0.1), )

Padding

通过给定的填充来插入其子的小控件

属性包括:

  • padding: 内边距
  • child: 子控件

示例:

new Padding( padding: new EdgeInsets.all(8.0), child: const Card(child: const Text('Hello World!')), )

设计讨论

为什么使用Padding小控件而不是Container和Container.padding属性?

两者之间没有任何区别。如果您提供Container.padding参数,则Container仅为您构建一个Padding小控件。 容器不直接实现其属性。相反,Container将许多更简单的小控件组合到一个方便的包中。例如,Container.padding属性将导致容器构建一个Padding小控件,而Container.decoration属性将导致容器构建一个DecoratedBox小控件。如果您发现Container方便,请随时使用它。如果没有,请随时以任何组合满足您的需求来构建这些更简单的小控件。实际上,Flutter中的大部分小控件只是其他更简单的小控件的组合。构成而不是继承是构建小控件的主要机制

Center

一个将子控件放置在自己内部中心的小控件。

属性包括:

  • widthFactor: 宽度系数
  • heightFactor: 高度系数
  • child: 子控件

说明: 宽度系数和高度系数是指Center的宽高是其子控件宽高的比率,例如heightFactor是2.0的话,那么Center的高度将是子控件高度的二倍。

示例: 略

Align

一个 通过自己对齐子控件,并且可能会根据子控件的大小来控制自己尺寸 的小控件

属性包括:

  • alignment: 对齐方式
  • heightFactor: 高度系数
  • widthFactor: 宽度系数
  • child: 子控件

示例: 略

FittedBox

控件
通过缩放和定位子控件来进行合适的调整

属性包括:

  • fit: 如何将子控件写入布局过程中分配的空间
  • alignment: 对齐方式
  • child: 子控件

示例: 略

AspectRatio

一个根据特定的长宽比来布局子控件的特殊控件

小控件首先尝试布局约束所允许的最大宽度。通过将给定的高宽比应用于宽度来确定小控件的高度,表示为宽度与高度的比率。 例如,16:9宽高比高宽比应为16.0 / 9.0。如果最大宽度是无限的,则通过将纵横比应用于最大高度来确定初始宽度。 现在考虑第二个示例,这次的宽高比为2.0,布局约束要求宽度在0.0到100.0之间,高度在0.0到100.0之间。我们将选择宽度100.0(允许的最大值)和高度50.0(以匹配宽高比)。 在这种情况下,如果宽高比为0.5,我们也会选择100.0的宽度(仍然是最大的宽度),我们将尝试使用200.0的高度。不幸的是,这违反了限制因素,因为子控件可能最多只有100.0像素。然后小控件将采用该值并再次应用宽高比以获得50.0的宽度。该宽度由约束条件允许,并且子节点的宽度为50.0,高度为100.0。如果宽度不被允许,小控件将继续遍历约束。如果在查询每个约束之后,小控件没有找到可行的大小,那么小控件将最终为满足布局约束但未能满足宽高比约束的子控件选择大小。

属性包括:

  • aspectRatio: 宽高比
  • child: 子控件

示例: 略

ConstrainedBox

一个对其子控件进行额外约束的控件

属性包括:

  • constraints: 约束
  • child: 子控件

示例:

new ConstrainedBox( constraints: const BoxConstraints.expand(), child: const Card(child: const Text('Hello World!')), )

Baseline

根据孩子的基线定位子控件的小控件

属性包括:

  • baseline:设定的距离控件顶部的基线位置
  • baselineType: 基线的类型
  • child: 子控件

示例: 略

FractionallySizedBox

一个小控件,其大小为其可用空间的一小部分

属性包括:

  • alignment: 对齐方式
  • heightFactor: 高度系数
  • widthFactor: 宽度系数
  • child: 子控件

示例: 略

IntrinsicHeight

一个根据内部子控件高度来调整高度

属性包括:

  • child: 子控件

示例: 略

说明:避免使用

IntrinsicWidth

一个根据内部子控件高度来调整高度

属性包括:

  • stepHeight: 控制子控件的高度为当前高度乘以这个值
  • stepwidth: 控制子控件的宽度为当前宽度乘以这个值
  • child: 子控件

示例: 略

说明:避免使用

LimitedBox

只有当它不受约束时才会限制它的大小

属性包括:

  • maxWidth: 不受限制的最大宽度
  • maxHeight: 不受限制的最大高度
  • child: 子控件

示例: 略

Offstage

一个可以控制其子控件显示或者隐藏的小控件

属性包括:

  • offstage: 是否隐藏
  • child: 子控件

OverflowBox

一个可以让子控件溢出其父控件的控件

属性包括:

  • alignment: 对齐方式
  • maxHeight: 最大高度
  • maxWidth: 最大宽度
  • minHeight: 最小高度
  • minWidth: 最小宽度
  • child: 子控件

示例: 略

SizedBox

一个具有特殊尺寸的控件

属性包括:

  • height: 高度
  • widht: 宽度
  • child: 子控件

示例:

new SizedBox( width: 200.0, height: 300.0, child: const Card(child: const Text('Hello World!')), )

SizedOverflowBox

一个具有特殊尺寸并且可能会溢出的小控件

属性包括:

  • alignment: 对齐方式
  • size: 尺寸
  • child: 子控件

示例: 略

Transform

一个在子控件绘制之前进行转换的控件

属性包括:

  • alignment: 对齐方式
  • origin: 原点
  • transform: 转场动画
  • transformHitTests: 是否在执行命中测试时应用转换
  • child: 子控件

示例:

new Container( color: Colors.black, child: new Transform( alignment: Alignment.topRight, transform: new Matrix4.skewY(0.3)..rotateZ(-math.PI / 12.0), child: new Container( padding: const EdgeInsets.all(8.0), color: const Color(0xFFE8581C), child: const Text('Apartment for rent!'), ), ), )

CustomSingleChildLayout

一个可以代理子控件布局的控件

属性包括:

  • delegate: 代理对象
  • child: 子控件

Multi-child layout widgets

Row

在水平方向上布局子部件的列表。

Troubleshooting

为什么我的行有黄色和黑色的警告条纹?

如果行的非灵活内容(未包含在扩展或灵活小部件中的那些内容)在一起大于行本身,则说该行已经溢出。当一行溢出时,该行没有任何剩余空间可用于在其展开和弹性子项之间共享。该行通过在溢出的边上绘制黄色和黑色条纹警告框来报告此情况。如果行外有空间,溢出量将以红色字体打印。

属性包括:

  • children: 子控件们
  • crossAxisAlignment: 子控件应该如何沿着横轴放置
  • direction: 主轴方向
  • mainAxisAlignment: 子控件应该如何沿着主轴放置
  • mainAxisSize: 主轴应该占据多少空间

说明:

Layout algorithm
This section describes how a Row is rendered by the framework. See BoxConstraints for an introduction to box layout models.

Layout for a Row proceeds in six steps:

  1. Layout each child a null or zero flex factor (e.g., those that are not Expanded) with unbounded horizontal constraints and the incoming vertical constraints. If the crossAxisAlignment is CrossAxisAlignment.stretch, instead use tight vertical constraints that match the incoming max height.
  2. Divide the remaining horizontal space among the children with non-zero flex factors (e.g., those that are Expanded) according to their flex factor. For example, a child with a flex factor of 2.0 will receive twice the amount of horizontal space as a child with a flex factor of 1.0.
  3. Layout each of the remaining children with the same vertical constraints as in step 1, but instead of using unbounded horizontal constraints, use horizontal constraints based on the amount of space allocated in step 2. Children with Flexible.fit properties that are FlexFit.tight are given tight constraints (i.e., forced to fill the allocated space), and children with Flexible.fit properties that are FlexFit.loose are given loose constraints (i.e., not forced to fill the allocated space).
  4. The height of the Row is the maximum height of the children (which will always satisfy the incoming vertical constraints).
  5. The width of the Row is determined by the mainAxisSize property. If the mainAxisSize property is MainAxisSize.max, then the width of the Row is the max width of the incoming constraints. If the mainAxisSize property is MainAxisSize.min, then the width of the Row is the sum of widths of the children (subject to the incoming constraints).
  6. Determine the position for each child according to the mainAxisAlignment and the crossAxisAlignment. For example, if the mainAxisAlignment is MainAxisAlignment.spaceBetween, any horizontal space that has not been allocated to children is divided evenly and placed between the children.

示例:

new Row( children: <Widget>[ const FlutterLogo(), const Expanded( child: const Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'), ), const Icon(Icons.sentiment_very_satisfied), ], )

Column

在垂直方向上布局子窗口小部件的列表

属性包括:

  • children: 子控件们
  • crossAxisAlignment: 子控件应该如何沿着横轴放置
  • direction: 主轴方向
  • mainAxisAlignment: 子控件应该如何沿着主轴放置
  • mainAxisSize: 主轴应该占据多少空间

示例:

new Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: <Widget>[ new Text('We move under cover and we move as one'), new Text('Through the night, we have one shot to live another day'), new Text('We cannot let a stray gunshot give us away'), new Text('We will fight up close, seize the moment and stay in it'), new Text('It’s either that or meet the business end of a bayonet'), new Text('The code word is ‘Rochambeau,’ dig me?'), new Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)), ], )

Stack

如果你想以一种简单的方式重叠几个子控件,这个类是有用的,例如有一些文本和图像,用渐变和按钮叠加

帧布局

属性包括:

  • alignment: 对齐方式
  • fit: 适应的方式
  • overflow: 是否修剪溢出的控件
  • textDirection: 文本方向,用于解决对齐的问题
  • children: 子控件们

示例: 略

IndexedStack

显示指定位置的子控件的控件,其高度等于最大的子控件高度

属性包括:

  • index: 要显示的子控件的位置
  • alignment: 对齐方式
  • children: 子控件们

示例: 略

GridView

可滚动的 2D子控件数组

属性包括:

  • childrenDelegate: 子控件提供者代理
  • gridDelegate: 控制字控件布局代理
  • controller: 滚动控制
  • padding: 内边距
  • scrollDirection: 滚动方向
  • children: 子控件们

示例:

new GridView.count( primary: false, padding: const EdgeInsets.all(20.0), crossAxisSpacing: 10.0, crossAxisCount: 2, children: <Widget>[ const Text('He\'d have you all unravel at the'), const Text('Heed not the rabble'), const Text('Sound of screams but the'), const Text('Who scream'), const Text('Revolution is coming...'), const Text('Revolution, they...'), ], )

Flow

一个实现流布局算法的布局

属性:

  • delegate: 控制子控件的变换矩阵
  • children: 子控件们

示例: 略

Table

一个实现表格布局算法的控件

属性包括:

  • border: 用于绘制边线
  • children: 子控件们
  • columnWidths: 控制列的宽度
  • defaultColumnWidth: 默认的列的宽度
  • defalutVerticalWidth: 默认的竖直方向的宽度

示例: 略

Wrap

一个小部件,它以多个水平或垂直运行显示其子项

属性包括:

  • alignment: 对齐方式
  • crossAxisAlignment: 主轴相反方向的对齐方式
  • direction: 主轴方向
  • runAlignment: 相反方向的对齐方式
  • runSpacing: 相邻的两个主轴相反方向的宽度
  • spacing: 子控件主轴方向的相邻宽度
  • children: 子控件们

示例:

new Wrap( spacing: 8.0, // gap between adjacent chips runSpacing: 4.0, // gap between lines children: <Widget>[ new Chip( avatar: new CircleAvatar(backgroundColor: Colors.blue.shade900, child: new Text('AH')), label: new Text('Hamilton'), ), new Chip( avatar: new CircleAvatar(backgroundColor: Colors.blue.shade900, child: new Text('ML')), label: new Text('Lafayette'), ), new Chip( avatar: new CircleAvatar(backgroundColor: Colors.blue.shade900, child: new Text('HM')), label: new Text('Mulligan'), ), new Chip( avatar: new CircleAvatar(backgroundColor: Colors.blue.shade900, child: new Text('JL')), label: new Text('Laurens'), ), ], )

ListBody

一个小部件,它沿着一个给定的轴顺序排列它的子元素,强制它们到另一个轴的父元素的维度

这个小部件很少直接使用。相反,请考虑使用ListView,它将相似的布局算法与滚动行为相结合,或者使用Column,这可以更灵活地控制垂直框的布局

属性包括:

  • mainAxis: 主轴方向
  • reverse: 列表主体是否将子控件定位在阅读方向
  • children: 子控件们

示例: 略

ListView

可滚动的线性小部件列表。
ListView是最常用的滚动小部件。它在滚动方向上一个接一个地显示其子项。
在交叉轴上,子控件需要填充ListView。

属性包括:

  • childrenDelegate: 子控件提供者代理
  • itemExtent: 子控件数量
  • controller: 滚动控制

示例:

new ListView.builder( padding: new EdgeInsets.all(8.0), itemExtent: 20.0, itemBuilder: (BuildContext context, int index) { return new Text('entry $index'); }, )

CustomMultiChildLayout

一个使用委托来定位和定位多个子项的小部件。

属性包括:

  • delegate: 用于控制布局子控件
  • children: 子控件们

示例: 略

Layout Helper

LayoutBuilder

构建一个可以依赖父控件大小的控件树

属性包括:

  • builder: 在布局时调用来构造小部件树。该构建器不得返回nul

示例:略

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容