Flutter布局全解

由上面的架构图可以看出来,flutter最上层是google 的纸墨设计Material Design(MaterialApp)组件,关于Material Design设计理念大家可以去官网安利一下啊material.io

在MaterialApp下面是所有组件的基类Widget,而在Widget的上层是statelessWdiget(无状态组件)、statefulWidget(有状态组件)和InheritedWidget(可以向子类View树种传递信息),包括我们在上篇文章中用到的Scaffold、Center、Text都是statelessWdiget、statefulWidget的子类。

开始之前,我们需要知道一些名词的含义和作用,在这里不懂的也没有关系,逐渐往后面看,往后面使用后,会有越来越清晰的理解。

  • MaterialApp

是我们app开发中常用的符合MaterialApp Design设计理念的入口Widget。

  • StatelessWidget

StatelessWidget是非动态的,它不依赖于除了传入数据以外的任何其他数据,这意味着改变其显示的唯一方式,就是改变传入其构造函数的参数。比如Text,Button,Icon这些控件。

  • StatefulWidget

StatefulWidget是动态的,他们允许我们创建一个能动随时间改变内容的widget,并且不依赖于其初始化时被传入的静态状态,可以随着用户的输入,各种形式的异步回包或其他形式的状态变化而变化。比如Image,CheckBox,Form这些控件。

  • Scaffold

Scaffold 翻译过来就是脚手架的意思,它实现了基本的 Material Design 可视化布局结构。简单的说,Scaffold就是一个提供 Material Design 设计中基本布局的 widget。

const Scaffold({
  Key key,
  this.appBar, // 标题栏
  this.body,  // 用于显示当前界面主要内容的Widget
  this.floatingActionButton, // 一个悬浮在body上的按钮,默认显示在右下角
  this.floatingActionButtonLocation, // 用于设置floatingActionButton显示的位置
  this.floatingActionButtonAnimator, // floatingActionButton移动到一个新的位置时的动画
  this.persistentFooterButtons, // 多状态按钮
  this.drawer, // 左侧的抽屉菜单
  this.endDrawer, //  右'侧的抽屉菜单
  this.bottomNavigationBar,// 底部导航栏。
  this.bottomSheet, // 显示在底部的工具栏
  this.backgroundColor,// 内容的背景颜色
  this.resizeToAvoidBottomPadding = true, // 控制界面内容 body 是否重新布局来避免底部被覆盖,比如当键盘显示的时候,重新布局避免被键盘盖住内容。
  this.primary = true,// Scaffold是否显示在页面的顶部
}) 

一个 MaterialApp 由多个 Scalfold 页面组成,每个 Scalfold 的主要结构如下:
AppBar:顶部导航栏
body:中间内容体
BottomNavigationBar:底部导航栏

  • Container

它是一个结合了绘制(painting)、定位(positioning)以及尺寸(sizing)widget的widget。

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,
  })

alignment:控制child的对齐方式
decoration:绘制在child后面的装饰

  • padding/margin

控件加入内/外边距。属性如下:

EdgeInsets.all(12),// 指定四个方向相同的值
EdgeInsets.fromLTRB(10, 20, 30, 40),// 分别指定四个方向的值
EdgeInsets.only(left: 10,right: 30),// 指定任意个方向的值EdgeInsets.symmetric(vertical: 10,horizontal: 50),//指定水平(left right)或垂直方向(top,bottom)的值。

  • 线性布局Row、Column

Row和Column分别是Flutter中的水平和垂直布局,对应Android里面的LinearLayout的水平垂直方向布局。

MainAxisAlignment (主轴)属性:

enum MainAxisAlignment {
//将子控件放在主轴的开始位置
start,
//将子控件放在主轴的结束位置
end,
//将子控件放在主轴的中间位置
center,
//将主轴空白位置进行均分,排列子元素,手尾没有空隙
spaceBetween,
//将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
spaceAround,
//将主轴空白区域均分,使各个子控件间距相等
spaceEvenly,
}

CrossAxisAlignment(交叉轴)属性:

enum CrossAxisAlignment {
//将子控件放在交叉轴的起始位置
start,
//将子控件放在交叉轴的结束位置
end,
//将子控件放在交叉轴的中间位置
center,
//使子控件填满交叉轴
stretch,
//将子控件放在交叉轴的上,并且与基线相匹配(不常用)
baseline,
}

配合Expanded使用,使Expanded中的child充满空白区域。Expanded组件必须用在Row、Column、Flex内。

Expanded(  
          flex: 1,
          child: Text(""),
        )

属性:

crossAxisAlignment:交叉轴子组件对齐方式
mainAxisAlignment:主轴子组件排列方式
mainAxisSize:Main 轴大小,相当于match_parent,wrap_content
verticalDirection:从下向上或从上向下摆放子组件

效果:


  • 相对布局Stack

Stack 这个是Flutter中布局用到的组件,跟Android中FrameLayout或RelativeLayout很像。是一个在布局中使用相当频繁的布局组件,相当重要的一个布局,这里当然要着重讲解。

Stack({
  Key key,
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})
  • alignment : 指的是子Widget的对其方式,子view从哪个方位开始对齐
  • fit :用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 多大就多大,StackFit.expand使子Widget的大小和父组件一样大
  • overflow :指子Widget 超出Stack时候如何显示,默认值是Overflow.clip,子Widget超出Stack会被截断,Overflow.visible超出部分还会显示的
  • Positioned:
    这个使用控制Widget的位置,通过他可以随意摆放一个组件,有点像绝对布局
Positioned({
  Key key,
  this.left,
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  @required Widget child,
})
  • 配合Align使用,可以单独设置子Widget的布局方位。
    Stack(
        children: [
           Align(
               alignment: Alignment.centerLeft,
               child: Text("你创作的,就是头条", style: TextStyle(fontSize: 15))
         )
    ]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352