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中通过 RowColumn来实现线性布局,也就是水平和垂直布局。

Row

水平布局:将 children中的组件按水平摆放

源码中的字段含义如下:

 
   
   
 
  1. Row({

  2. Key key,

  3. MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,//children在主轴方向上的对齐方式

  4. MainAxisSize mainAxisSize = MainAxisSize.max,// 在主轴方向占有空间的值

  5. CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//children在交叉轴方向的对齐方式

  6. TextDirection textDirection,// 水平方向上的文字摆放顺序

  7. VerticalDirection verticalDirection = VerticalDirection.down,// 竖直方向上 children 摆放顺序

  8. TextBaseline textBaseline,// 文本基准线

  9. List<Widget> children = const <Widget>[],// 子 widget 集合

  10. })

每个字段又有相关的参数可设置,熟悉各个字段值的含义有助于我们快速准确使用字段。

MainAxisAlignment

MainAxisAlignment 的取值有:start,end,center,spaceBetween,spaceAround,spaceEvenly效果图如下:Flutter 多子 Widget 布局之线性布局 Row、Column

伪代码如下:

 
   
   
 
  1. Row(

  2. mainAxisAlignment: MainAxisAlignment.end,

  3. children: <Widget>[

  4. Text(" hello "),

  5. Text(" I am MainAxisAlignment.end "),

  6. ],

  7. ),

  • start:将 children从屏幕左侧起点开始排列

  • end:将 children从屏幕右侧做起点开始排列

  • center:将 children从屏幕中间做起点开始排列

  • spaceBetween:将主轴方向上的空白区域均分,使得 children之间的空白区域相等,首尾 child都靠近首尾,没有间隙;

  • spaceAround:将主轴方向上的空白区域均分,使得 children之间的空白区域相等,但是首尾 child的空白区域为 1/2

  • spaceEvenly:将主轴方向上的空白区域均分,使得 children之间的空白区域相等,包括首尾 child

再来细看 spaceBetween,spaceAround,spaceEvenly 这三个字段效果图对比上面的文字描述:

Flutter 多子 Widget 布局之线性布局 Row、Column

伪代码如下:

 
   
   
 
  1. Row(

  2. mainAxisAlignment: MainAxisAlignment.spaceBetween,

  3. children: <Widget>[

  4. Text(" hello "),

  5. Text(" word "),

  6. Text(" spaceBetween "),

  7. ],

  8. ),

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:文本从左向右排列(默认)

效果图:Flutter 多子 Widget 布局之线性布局 Row、Column

伪代码:

 
   
   
 
  1. Row(

  2. mainAxisAlignment: MainAxisAlignment.start,

  3. textDirection: TextDirection.ltr,

  4. children: <Widget>[

  5. Text(" hello "),

  6. Text(" I am MainAxisAlignment.start "),

  7. ],

  8. ),

MainAxisSize

MainAxisSize 的取值有:min,max

  • max:最大化使用主轴方向的可用空间(默认)

  • min:与max相反,是最小化使用主轴方向的可用空间

Flutter 多子 Widget 布局之线性布局 Row、Column

伪代码:

 
   
   
 
  1. Row(

  2. mainAxisAlignment: MainAxisAlignment.start,

  3. mainAxisSize: MainAxisSize.min,

  4. children: <Widget>[

  5. Text(" hello "),

  6. Text(" I am MainAxisAlignment.start "),

  7. ],

  8. ),

VerticalDirection

竖直方向上( child)摆放顺序, VerticalDirection 的取值有:up,down

  • up: 表示 Row纵轴(垂直)从上到下进行布局

  • down: 表示Row纵轴(垂直)从下到上进行布局

Column

垂直布局, Column参数和 Row一样,不同的是布局方向为垂直,主轴纵轴方向相反。

MainAxisAlignment

Column的主轴是垂直方向,交叉轴暂时没想到好的示例,这里先不介绍了。

CrossAxisAlignment

效果图如下:

伪代码:

 
   
   
 
  1. Column(

  2. crossAxisAlignment: CrossAxisAlignment.center,

  3. children: <Widget>[

  4. Text(" hello "),

  5. Text(" I am CrossAxisAlignment.center "),

  6. ],

  7. ),

从效果图上看 stretchbaseline还是区分不了。所以再来看了效果图:

伪代码实现:

 
   
   
 
  1. Column(

  2. children: <Widget>[

  3. SizedBox(

  4. height: 30,

  5. ),

  6. Column(

  7. crossAxisAlignment: CrossAxisAlignment.stretch,

  8. children: <Widget>[

  9. Text(" hello "),

  10. Text(" I am CrossAxisAlignment.stretch "),

  11. ],

  12. ),

  13. SizedBox(

  14. height: 30,

  15. ),

  16. Column(

  17. crossAxisAlignment: CrossAxisAlignment.baseline,

  18. textBaseline: TextBaseline.alphabetic,

  19. children: <Widget>[

  20. Text(" hello "),

  21. Text(" I am CrossAxisAlignment.baseline "),

  22. ],

  23. ),

  24. ],

  25. ));

分析一波: baseline的含义是:在交叉轴方向,使得 childrenbaseline对齐。而现在是 Column组件,交叉轴默认是水平方向,并且默认的主轴方向是居中开始, 所以文字是从水平方向居中开始摆列。因此上面的效果图也就很好解释了。

stretch的含义是:让 children填满交叉轴方向,从效果图来看没毛病。

end.

看到这的可以三连(在看、评论、转发)走起了~


以上是关于Flutter布局全解的主要内容,如果未能解决你的问题,请参考以下文章

Flutter构建布局之路

Flutter 多子 Widget 布局之线性布局 RowColumn

flutter学习常见布局组件

flutter学习常见布局组件

Flutter自定义布局套路

Flutter 布局相关知识点