Flutter布局全解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter布局全解相关的知识,希望对你有一定的参考价值。
参考技术A 由上面的架构图可以看出来,flutter最上层是google 的纸墨设计Material Design(MaterialApp)组件,关于Material Design设计理念大家可以去官网安利一下啊 material.io在MaterialApp下面是所有组件的基类Widget,而在Widget的上层是statelessWdiget(无状态组件)、statefulWidget(有状态组件)和InheritedWidget(可以向子类View树种传递信息),包括我们在上篇文章中用到的Scaffold、Center、Text都是statelessWdiget、statefulWidget的子类。
开始之前,我们需要知道一些名词的含义和作用,在这里不懂的也没有关系,逐渐往后面看,往后面使用后,会有越来越清晰的理解。
是我们app开发中常用的符合MaterialApp Design设计理念的入口Widget。
StatelessWidget是非动态的,它不依赖于除了传入数据以外的任何其他数据,这意味着改变其显示的唯一方式,就是改变传入其构造函数的参数。比如Text,Button,Icon这些控件。
StatefulWidget是动态的,他们允许我们创建一个能动随时间改变内容的widget,并且不依赖于其初始化时被传入的静态状态,可以随着用户的输入,各种形式的异步回包或其他形式的状态变化而变化。比如Image,CheckBox,Form这些控件。
Scaffold 翻译过来就是脚手架的意思,它实现了基本的 Material Design 可视化布局结构。简单的说,Scaffold就是一个提供 Material Design 设计中基本布局的 widget。
一个 MaterialApp 由多个 Scalfold 页面组成,每个 Scalfold 的主要结构如下:
AppBar:顶部导航栏
body:中间内容体
BottomNavigationBar:底部导航栏
它是一个结合了绘制(painting)、定位(positioning)以及尺寸(sizing)widget的widget。
alignment:控制child的对齐方式
decoration:绘制在child后面的装饰
控件加入内/外边距。属性如下:
Row和Column分别是Flutter中的水平和垂直布局,对应android里面的LinearLayout的水平垂直方向布局。
MainAxisAlignment (主轴)属性:
CrossAxisAlignment(交叉轴)属性:
配合Expanded使用,使Expanded中的child充满空白区域。Expanded组件必须用在Row、Column、Flex内。
属性:
效果:
Stack 这个是Flutter中布局用到的组件,跟Android中FrameLayout或RelativeLayout很像。是一个在布局中使用相当频繁的布局组件,相当重要的一个布局,这里当然要着重讲解。
Flutter 多子 Widget 布局之线性布局 RowColumn
欢迎新关注的朋友,在这里主要分享微信小程序、Flutter、Android、NodeJS相关的文章,说牛批点就是全栈技术(手动狗头)。
目前我在学 Flutter 这个框架,所以最近的文章基本都是 Flutter 相关。今年计划还会写微信小程序开发系列文章,欢迎持续关注。
主要参考:Flutter 布局(七)- Row、Column详解
线性布局 Row、Column
Flutter
中通过Row
和Column
来实现线性布局,也就是水平和垂直布局。
Row
水平布局:将
children
中的组件按水平摆放
源码中的字段含义如下:
Row({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,//children在主轴方向上的对齐方式
MainAxisSize mainAxisSize = MainAxisSize.max,// 在主轴方向占有空间的值
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//children在交叉轴方向的对齐方式
TextDirection textDirection,// 水平方向上的文字摆放顺序
VerticalDirection verticalDirection = VerticalDirection.down,// 竖直方向上 children 摆放顺序
TextBaseline textBaseline,// 文本基准线
List<Widget> children = const <Widget>[],// 子 widget 集合
})
每个字段又有相关的参数可设置,熟悉各个字段值的含义有助于我们快速准确使用字段。
MainAxisAlignment
MainAxisAlignment
的取值有:start,end,center,spaceBetween,spaceAround,spaceEvenly
效果图如下:
伪代码如下:
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(" hello "),
Text(" I am MainAxisAlignment.end "),
],
),
start
:将children
从屏幕左侧起点开始排列end
:将children
从屏幕右侧做起点开始排列center
:将children
从屏幕中间做起点开始排列spaceBetween
:将主轴方向上的空白区域均分,使得children
之间的空白区域相等,首尾child
都靠近首尾,没有间隙;spaceAround
:将主轴方向上的空白区域均分,使得children
之间的空白区域相等,但是首尾child
的空白区域为1/2
;spaceEvenly
:将主轴方向上的空白区域均分,使得children
之间的空白区域相等,包括首尾child
;
再来细看 spaceBetween,spaceAround,spaceEvenly
这三个字段效果图对比上面的文字描述:
伪代码如下:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(" hello "),
Text(" word "),
Text(" spaceBetween "),
],
),
CrossAxisAlignment
CrossAxisAlignment
表示交叉轴,Row
的主轴是水平方向,交叉轴暂时没想到好的示例,这里就不做图示了。
CrossAxisAlignment
的取值有:baseline,center,end,start,stretch
baseline
:在交叉轴方向,使得children
的baseline
对齐center
:children
在交叉轴上居中展示end
:children
在交叉轴上末尾展示start
:children
在交叉轴上起点处展示stretch
:让children
填满交叉轴方向
TextDirection
水平方向上的文字(
child
)摆放顺序,TextDirection
的取值有:rtl,ltr
rtl
:文本从右向左排列
ltr
:文本从左向右排列(默认)
效果图:
伪代码:
Row(
mainAxisAlignment: MainAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Text(" hello "),
Text(" I am MainAxisAlignment.start "),
],
),
MainAxisSize
MainAxisSize
的取值有:min,max
max
:最大化使用主轴方向的可用空间(默认)
min
:与max相反,是最小化使用主轴方向的可用空间
伪代码:
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(" hello "),
Text(" I am MainAxisAlignment.start "),
],
),
VerticalDirection
竖直方向上(
child
)摆放顺序,VerticalDirection
的取值有:up,down
up
: 表示Row
纵轴(垂直)从上到下进行布局
down
: 表示Row纵轴(垂直)从下到上进行布局
Column
垂直布局,
Column
参数和Row
一样,不同的是布局方向为垂直,主轴纵轴方向相反。
MainAxisAlignment
Column
的主轴是垂直方向,交叉轴暂时没想到好的示例,这里先不介绍了。
CrossAxisAlignment
效果图如下:
伪代码:
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(" hello "),
Text(" I am CrossAxisAlignment.center "),
],
),
从效果图上看 stretch、baseline
还是区分不了。所以再来看了效果图:
伪代码实现:
Column(
children: <Widget>[
SizedBox(
height: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(" hello "),
Text(" I am CrossAxisAlignment.stretch "),
],
),
SizedBox(
height: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: <Widget>[
Text(" hello "),
Text(" I am CrossAxisAlignment.baseline "),
],
),
],
));
分析一波: baseline
的含义是:在交叉轴方向,使得 children
的 baseline
对齐。而现在是 Column
组件,交叉轴默认是水平方向,并且默认的主轴方向是居中开始, 所以文字是从水平方向居中开始摆列。因此上面的效果图也就很好解释了。
stretch
的含义是:让 children
填满交叉轴方向,从效果图来看没毛病。
end.
看到这的可以三连(在看、评论、转发)走起了~
以上是关于Flutter布局全解的主要内容,如果未能解决你的问题,请参考以下文章