Flutter开发实战初级(2)页面布局详解

  • 初级基础系列

Flutter开发实战初级(1)ListView详解git

Flutter开发实战初级(2)布局详解github

  • 项目实战系列

Flutter开发实战 高仿微信(1)首页swift

Flutter开发实战 高仿微信(2)发现页数组

Flutter开发实战初级(2)页面布局详解

本篇博客Demo下载点击这里:Flutter布局Demo微信

1. Flutter布局实战讲解

1.1 布局坐标

首先新建一个Flutter项目 我这里命名为flutter_layoutdemo, less

新建一个Flutter项目

接下来咱们建立一个用来练习布局的layout_demo.dart文件,直接按快捷键“Command + N”iphone

建立一个用来练习布局的layout_demo.dart文件

而后找到main.dart里面的MyApp类,替换掉系统默认的代码,以下图所示: ide

替换掉系统默认的代码

替换掉以后,咱们直接按快捷键“Control+R” 编译运行到模拟器上面,能够选择安卓或者iOS模拟器,也能够选择运行在真机上面,以下图选择你想运行的模拟器: 布局

选择你想运行的模拟器

这里我选择的是iphone 11 模拟器,运行结果以下:post

iphone 11 模拟器,运行结果

接下来咱们在layoutDemo类的build方法里面加入一些小部件

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Center(
        child: Text('kongyulu'),
      ),
    );
  }
}
复制代码

"Control + R " 编译运行

居中显示

其实咱们还能够经过alignment 属性是布局居中显示,这个相似于IOS 的UILabel的对齐属性。这样咱们能够修改代码以下:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      alignment: Alignment(0.0, 0.0),
      child: Text('kongyulu2')
    );
  }
复制代码

咱们热更新一下,能够看到效果以下:

alignment属性居中显示

下面咱们简单介绍一下aligment属性: 实际上咱们上面代码用的相对布局,坐标原点在中心,咱们aligment属性 Alignment(x,y)传入x,y的坐标,这里传入(0,0)标识在中心位置,以下图所示:

alignment属性坐标详解

如上图所示,Alignment(-1,-1)标识在左上角,Alignment(1,1)在右下角,Alignment(-1,1)在左下角,Alignment(1,-1)在右上角,下面咱们能够简单验证一下

若是咱们把alignment属性改成Alignment(1,0),效果以下:

把alignment属性改成Alignment(1,0)
若是咱们把alignment属性改成Alignment(0,1),效果以下:
在这里插入图片描述

若是咱们把alignment属性改成Alignment(-1,-1),效果以下:

把alignment属性改成Alignment(-1,-1)

由此咱们能够知道(-1,-1)在左上角, (1,1)在右上角,

1.2 横向布局Row

接下来咱们讲解一下横向布局Row,咱们修改一下代码,增长一个Row布局,代码以下:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      alignment: Alignment(0.0, 0.0),
      child: Row(
        children: <Widget>[
          Icon(Icons.add),
          Icon(Icons.access_alarm),
          Icon(Icons.account_balance_wallet),
        ],
      )
    );
  }
}
复制代码

热更新一下,效果以下:

横向布局Row

Row表示横向布局,里面须要传入一个Widget数组,数组里面的Widget小部件都横向排列。咱们能够看到小部件默认有点小,咱们来修改一下大小将size改成80

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      alignment: Alignment(0.0, 0.0),
      child: Row(
        children: <Widget>[
          Icon(Icons.add,size: 80,),
          Icon(Icons.access_alarm,size: 80,),
          Icon(Icons.account_balance_wallet,size: 80,),
        ],
      )
    );
  }
}

复制代码

从新运行一下效果以下:

size改成80后的大小

若是咱们想跟里面的小部件添加背景颜色,咱们只须要将这个小部件放到一个新的Container容器里面包装一下,便可使用Container里面的相关属性,设置颜色等属性。

咱们再修改一下代码,给小部件添加背景颜色:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      alignment: Alignment(0.0, 0.0),
      child: Row(
        children: <Widget>[
          Container(child:Icon(Icons.add,size: 80,) ,color: Colors.blue,)
          ,
          Container(child:Icon(Icons.access_alarm,size: 80,) ,color: Colors.yellow,)
          ,
          Container(child:Icon(Icons.account_balance_wallet,size: 80,) ,color: Colors.green,)
          ,

        ],
      )
    );
  }
}
复制代码

从新运行一下效果以下:

给小部件添加背景颜色

1.3 纵向布局Column

纵向布局时垂直方向的布局,更横向布局相对应。咱们只须要将上面的横向布局代码的Row改成Column,以下:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      alignment: Alignment(0.0, 0.0),
      child: Column(
        children: <Widget>[
          Container(child:Icon(Icons.add,size: 80,) ,color: Colors.blue,)
          ,
          Container(child:Icon(Icons.access_alarm,size: 80,) ,color: Colors.yellow,)
          ,
          Container(child:Icon(Icons.account_balance_wallet,size: 80,) ,color: Colors.green,)
          ,

        ],
      )
    );
  }
}
复制代码

热更新一下,咱们来看一下效果:

纵向布局

1.4 层级布局Stack

咱们再将上面的代码修改成Stack层级布局看看什么效果,修改代码以下:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      alignment: Alignment(0.0, 0.0),
      child: Stack(
        children: <Widget>[
          Container(child:Icon(Icons.add,size: 80,) ,color: Colors.blue,)
          ,
          Container(child:Icon(Icons.access_alarm,size: 80,) ,color: Colors.yellow,)
          ,
          Container(child:Icon(Icons.account_balance_wallet,size: 80,) ,color: Colors.green,)
          ,

        ],
      )
    );
  }
}
复制代码

咱们快捷键“Command+||” 热更新一下,运行效果以下:

层级布局stack

原本是三个,咱们只看到了最后一个小部件,说明另外两个被遮挡了,咱们来修改一下每一个小部件的大小:

修改小部件大小后的stack布局效果

由此咱们能够知道 Row横向布局对应x轴,Column纵向布局对应y轴,Stack层次布局对应z轴,咱们由x,y,z能够很容易布局想要的效果。

1.5 主轴 mainAxisAlignment

咱们的Row,Column都有两个很是重要的属性:主轴mainAxisAlignment 和 交叉轴

其中主轴须要传入一个对象,咱们查看源码能够看到:

主轴和交叉轴定义

主轴属性传入一个MainAxisAlignment对象,咱们能够看到它有下面结构属性:

在这里插入图片描述

  • MainAxisAlignment.center: 表示沿着主轴方向居中显示,若是Row横向布局,则是沿着x轴从左到右横着居中排列显示,若是是Column纵向布局,则是沿着y轴从上往下,纵向居中显示

若是Row横向布局,则是沿着x轴从左到右横着居中排列显示

若是是Column纵向布局,则是沿着y轴从上往下,纵向居中显示

  • MainAxisAlignment.end :

若是Row横向布局,则是沿着x轴从左到右横着居中,靠右对齐排列显示

若是Row横向布局,则是沿着x轴从左到右横着居中,靠右对齐排列显示

若是是Column纵向布局,则是沿着y轴从上往下,纵向居中, 而且靠底部对齐显示

若是是Column纵向布局,则是沿着y轴从上往下,纵向居中, 而且靠底部对齐显示

  • MainAxisAlignment.spaceAround: 就是将主轴方向剩下的空间平均分配给每一个子控件。

若是Row横向布局,则水平方向剩下的空间平均分配在每一个空间的周围

水平方向剩下的空间平均分配在每一个空间的周围

若是是Column纵向布局,则垂直方向剩下的空间平均分配在每一个空间的周围

垂直方向剩下的空间平均分配在每一个空间的周围
在这里插入图片描述

  • MainAxisAlignment.spaceBetween: 剩下的空间平均分配到每一个小部件之间的间隔。
    在这里插入图片描述

在这里插入图片描述

  • MainAxisAlignment.spaceEvently: 剩下空间和小部件一块儿平均分配,是等间距的分配。

在这里插入图片描述
在这里插入图片描述

  • MainAxisAlignment.start : 表示主轴开始的方向, 也是默认值

若是是Row布局,MainAxisAlignment.start 主轴效果以下:

表示主轴开始的方向, 也是默认值
若是是Column布局, MainAxisAlignment.start 主轴效果以下:
若是是Column布局,MainAxisAlignment.start主轴效果

1.6 交叉轴 CrossAxisAlignment

CrossAxisAlignment交叉轴拥有的属性以下:

交叉轴

交叉轴默认的属性是center 居中显示

  • CrossAxisAlignment.baseline : 这个baseline属性不能单独使用,须要结合其余属性配合使用,不然会报错:
    须要结合其余属性配合使用,不然会报错
    咱们修改一下代码,增长textBaseline: TextBaseline.alphabetic属性,配合使用,由于baseline属性须要针对文本才能体现效果,因此咱们还须要在每一个小部件里面增长一个文本标签

主轴为x轴,沿交叉轴y轴方向底部对齐

主轴为x轴,沿交叉轴y轴方向底部对齐
咱们将标签的背景大小设置一致更好对比:
将标签的背景大小设置一致更好对比

纵向布局时,baseline属性使字体沿交叉轴左对齐

纵向布局时,baseline属性使字体沿交叉轴左对齐

咱们再来看一下去掉baseline属性的效果:

去掉baseline属性的效果

  • CrossAxisAlignment.center :
    在这里插入图片描述

在这里插入图片描述

  • CrossAxisAlignment.end :
    在这里插入图片描述

在这里插入图片描述

  • CrossAxisAlignment.start :
    CrossAxisAlignment.start 做为x轴

Row布局主轴是x轴,交叉轴是y轴

  • CrossAxisAlignment.stretch :
    在这里插入图片描述
    在这里插入图片描述

1.7 Expanded自动填充

Expanded 是一种比较灵活的布局方案,它使得子部件随之父控件的大小自动填充

咱们接下来将上面的代码修改一下,将每一个小部件放入Expanded布局中,修改后代码以下:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      alignment: Alignment(0.0, 0.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.baseline,
        textBaseline: TextBaseline.alphabetic,
        children: <Widget>[
          Expanded(child: Container(child:Text('孔雨露',style: TextStyle(fontSize: 15),) ,color: Colors.blue,height: 80,),)
          ,
          Expanded(child:Container(child:Text('努力',style: TextStyle(fontSize: 30),) ,color: Colors.yellow,height: 80,),)
          ,
          Expanded(child: Container(child:Text('坚持',style: TextStyle(fontSize: 60),) ,color: Colors.green,height: 80,),)
          ,

        ],
      )
    );
  }
}
复制代码

运行效果以下:

Expended自动填充布局

咱们将上面的代码的布局Column改成Row横向布局,效果以下:

沿x轴自动填充

由此咱们知道,若是咱们设置了Expanded自动填充,假设咱们使用Row横向布局咱们不须要设置宽度(就算设置了宽度也不会生效,没有意义),沿主轴x轴每一个子部件自动填充拉伸满,不会在主轴方向留下空隙,同理,若是是纵向布局,则设置Expanded自动填充后,不须要设置高度(就算设置了高度也不会生效,没有意义),沿主轴y会自动填充拉伸。

这个属性对应咱们文字很长时,会根据宽度自动换行,以下图:

超过最大宽度后,自动换行

接下来,若是咱们看一下若是上面的三个小部件,不是每一个都使用expanded布局呢,如今咱们改一下代码,把中间的那个小部件改成不是expanded布局。

有一个小部件不使用Expanded属性

1.8 Alignment属性

咱们将上面的代码简化一下,改成以下:

Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      alignment: Alignment(0.0, 0.0),
      child: Container(child:
      Icon(Icons.add,size: 30,),height: 40,
        color:Colors.blue,)
    );
  }
复制代码

运行效果以下:

Alignment属性

咱们通常用alignment根据比例来显示位置,

相关文章
相关标签/搜索