前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Flutter必备]-Flex布局完全解读

[Flutter必备]-Flex布局完全解读

作者头像
张风捷特烈
发布2020-04-30 15:23:07
1.1K0
发布2020-04-30 15:23:07
举报
0.前言

Flex布局是Flutter的五虎上将之一,虎父无犬子,其子Row和Column也能力非凡 你有没有被mainAxisAlignment,crossAxisAlignment弄得晕头转向,本文将助你将他们纳入麾下。 先看一下父子三人在Flutter布局体系中的位置:多子组件布局


1.Flex的属性一览

属性名

类型

默认值

简介

direction

Axis

@required

轴向

mainAxisAlignment

MainAxisAlignment

start

主轴方向对齐方式

crossAxisAlignment

CrossAxisAlignment

center

交叉轴方向对齐方式

mainAxisSize

MainAxisSize

max

主轴尺寸

textDirection

TextDirection

null

文本方向

verticalDirection

VerticalDirection

down

竖直方向

textBaseline

TextBaseline

null

基线类型

children

List

[]

内部孩子


2.轴向:direction:Axis
代码语言:javascript
复制
enum Axis {
  horizontal,//水平
  vertical,//竖直
}

也就是水平排放还是竖直排放,可以看出默认情况下都是主轴顶头,交叉轴居中 比如horizontal下主轴为水平轴,交叉轴则为竖直。也就是水平顶头,竖直居中 这里使用MultiShower快速展示,更好的对比出不同之处,MultiShower详见

代码语言:javascript
复制
var direction =[Axis.horizontal,Axis.vertical];
var show = MultiShower(direction,(e){
  return Flex(
    direction: e,
    children: <Widget>[redBox,blueBox,yellowBox,greenBox],

  );
},color: Colors.black12,width: 300,height: 200);

var redBox= Container(
  color: Colors.red,
  height: 50,
  width: 50,
);

var blueBox= Container(
  color: Colors.blue,
  height: 30,
  width: 60,
);

var yellowBox= Container(
  color: Colors.yellow,
  height: 50,
  width: 100,
);

var greenBox= Container(
  color: Colors.green,
  height: 60,
  width: 60,
);

3.主轴方向:mainAxisAlignment:MainAxisAlignment

主轴方向的排布规则,这里以水平为例,主轴为水平方向。竖直类比即可

代码语言:javascript
复制
enum MainAxisAlignment {
  start,//顶头
  end,//接尾
  center,//居中
  spaceBetween,//顶头接尾,其他均分
  spaceAround,//中间的孩子均分,两头的孩子空一半
  spaceEvenly,//均匀平分
代码语言:javascript
复制
testMainAxisAlignment(){
  var redBox= Container(
    color: Colors.red,
    height: 50,
    width: 50,
  );

  var blueBox= Container(
    color: Colors.blue,
    height: 30,
    width: 60,
  );

  var yellowBox= Container(
    color: Colors.yellow,
    height: 10,
    width: 10,
  );

  var greenBox= Container(
    color: Colors.green,
    height: 50,
    width: 10,
  );

  var mainAxisAlignment =[
  MainAxisAlignment.start,MainAxisAlignment.center,
  MainAxisAlignment.end,MainAxisAlignment.spaceAround,
  MainAxisAlignment.spaceBetween,MainAxisAlignment.spaceEvenly];

  var show = MultiShower(mainAxisAlignment,(e){
    return Flex(
      direction: Axis.horizontal,
      mainAxisAlignment: e,
      children: <Widget>[redBox,blueBox,yellowBox,greenBox],

    );
  },color: Colors.black12,width: 200,height: 150);
  return show;
}
复制代码

4.交叉轴方向:crossAxisAlignment:CrossAxisAlignment
代码语言:javascript
复制
enum CrossAxisAlignment {
  start,//顶头
  end,//接尾
  center,//居中
  stretch,//伸展
  baseline,//基线
}

还是水平为例,交叉轴便是竖轴,这里可以看出他们的布局行为 其中需要注意的是CrossAxisAlignment.baseline使用时必须有textBaseline 其中textBaseline确定对齐的是那种基线,分为alphabeticideographic

代码语言:javascript
复制
testCrossAxisAlignment(){
  var redBox= Container(
    color: Colors.red,
    height: 50,
    width: 50,
  );

  var blueBox= Container(
    color: Colors.blue,
    height: 30,
    width: 60,
  );

  var yellowBox= Container(
    color: Colors.yellow,
    height: 10,
    width: 10,
  );

  var greenBox= Container(
    color: Colors.green,
    height: 50,
    width: 10,
  );
  
  var crossAxisAlignment =[CrossAxisAlignment.start,CrossAxisAlignment.center,
    CrossAxisAlignment.end,CrossAxisAlignment.stretch,CrossAxisAlignment.baseline];

  var show = MultiShower(crossAxisAlignment,(e){
    return Flex(
      direction: Axis.horizontal,
      crossAxisAlignment: e,
      textBaseline: TextBaseline.alphabetic,//基线类型
      children: <Widget>[redBox,blueBox,yellowBox,greenBox],

    );
  },color: Colors.black12,width: 200,height: 140);

  return show;
}
复制代码

5.主轴尺寸:mainAxisSize
代码语言:javascript
复制
enum MainAxisSize {
  min,
  max,
}

当父容器的宽未约束,Flex默认会将自身尽可能延伸,这便是MainAxisSize.max

此时改为MainAxisSize.min时,它不会延伸自己的区域,自会包裹内容

代码语言:javascript
复制
testMainAxisSize(){
  var redBox= Container(
    color: Colors.red,
    height: 50,
    width: 50,
  );

  var blueBox= Container(
    color: Colors.blue,
    height: 30,
    width: 60,
  );

  var yellowBox= Container(
    color: Colors.yellow,
    height: 10,
    width: 10,
  );

  var greenBox= Container(
    color: Colors.green,
    height: 50,
    width: 10,
  );

  return Center(child: Flex(
    direction: Axis.horizontal,
    mainAxisSize: MainAxisSize.max,
    children: <Widget>[redBox,blueBox,yellowBox,greenBox],

  ),);
}
复制代码

6.文字方向:textDirection:TextDirection
代码语言:javascript
复制
enum TextDirection {
  ltr,//从左到右
  rtl,//从右到左
}

这个非常好理解,不多言了

代码语言:javascript
复制
testTextDirection(){
  var redBox= Container(
    color: Colors.red,
    height: 50,
    width: 50,
  );

  var blueBox= Container(
    color: Colors.blue,
    height: 30,
    width: 60,
  );

  var yellowBox= Container(
    color: Colors.yellow,
    height: 10,
    width: 10,
  );

  var greenBox= Container(
    color: Colors.green,
    height: 50,
    width: 10,
  );

  var textDirection =[TextDirection.ltr,TextDirection.rtl];
  var show = MultiShower(textDirection,(e){
    return Flex(
      direction: Axis.horizontal,
      textDirection: e,
      children: <Widget>[redBox,blueBox,yellowBox,greenBox],

    );
  },color: Colors.black12,width: 200,height: 140);
  return show;
}
复制代码

7.竖直方向排序:verticalDirection:VerticalDirection
代码语言:javascript
复制
enum VerticalDirection{
    up,
    down,
}
代码语言:javascript
复制
testVerticalDirection(){
  var redBox= Container(
    color: Colors.red,
    height: 50,
    width: 50,
  );

  var blueBox= Container(
    color: Colors.blue,
    height: 30,
    width: 60,
  );

  var yellowBox= Container(
    color: Colors.yellow,
    height: 10,
    width: 10,
  );

  var greenBox= Container(
    color: Colors.green,
    height: 50,
    width: 10,
  );

  var verticalDirection =[VerticalDirection.up,VerticalDirection.down];

  var show = MultiShower(verticalDirection,(e){
    return Flex(
      direction: Axis.vertical,
      verticalDirection: e
      children: <Widget>[redBox,blueBox,yellowBox,greenBox],

    );
  },color: Colors.black12,width: 200,height: 140);

  return show;
}
复制代码

8.基线对齐方式:textBaseline:TextBaseline
代码语言:javascript
复制
enum TextBaseline {
  alphabetic,
  ideographic,
}
代码语言:javascript
复制
testTextBaseline(){
  var redBox= Text(
    "张风捷特烈",style: TextStyle(fontSize: 20,backgroundColor: Colors.red),
  );

  var blueBox= Text(
    "toly",style: TextStyle(fontSize: 50,backgroundColor: Colors.blue),
  );

  var yellowBox=  Text(
    "1994",style: TextStyle(fontSize: 30,backgroundColor: Colors.green),
  );

  var textBaseline =[TextBaseline.alphabetic,TextBaseline.ideographic];

  var show = MultiShower(textBaseline,(e){
    return Flex(
      direction: Axis.horizontal,
      crossAxisAlignment: CrossAxisAlignment.baseline,
      textBaseline: e,
      children: <Widget>[redBox,blueBox,yellowBox],
    );
  },color: Colors.black12,width: 300,height: 140);

  return show;
}
复制代码

至此,Flutter中的Flex布局就已经完全解读完了。 其中Flutter的孩子Row是direction: Axis.horizontal,Column是direction: Axis.vertical, 其他的属性都是类似的,相当于Flex的简化版,所以Flex在手,天下我有。


Expanded与Flex的搭配--- 更新于2019.1.22

还要一点是关于Expanded,也比较保用,它能与Flex布局结合,变更孩子尺寸

代码语言:javascript
复制
c1:绿色  c2:红色  c3:黄色
1).Expanded--c2:c1和c3将不变,c2延伸自己占满剩余部分
2).同时Expanded--c2和c3,最终c2和c3的长度是一样的
3).同时Expanded--c1,c2和c3,最终c1,c2,c3长度都是一样的

9.用Flex布局写个小例子

光说不练假把式,光练不说空把式,下面就用一个布局来实际看一下Flex的强大

  • 首先简单的分析一下
代码语言:javascript
复制
1.由上中下三行,可以用Column
2.第一行由图标,文字和文字组成,其中两头分处左右,可以用Expanded处理  
3.中间比较复杂由一个Row中包含两部分,左边是一个两行Column的内容,右边是文字  
4.底部是一个Row,主轴对齐是start
  • 布局代码
代码语言:javascript
复制
showItem() {
  var infoStyle = TextStyle(color: Color(0xff999999), fontSize: 13);
  var littleStyle = TextStyle(color: Colors.black, fontSize: 16);

  var top = Row(//顶部,通过Flex布局的Row进行横向排列,Expanded中间
    children: <Widget>[
      Image.asset("images/icon_head.png", width: 20, height: 20),
      Expanded(
        child: Padding(
          child: Text("张风捷特烈"),
          padding: EdgeInsets.only(left: 4),
        ),
      ),
      Text(
        "Flutter/Dart",
        style: infoStyle,
      )
    ],
  );

  var content = Column(//中间文字内容,交叉轴为start
    mainAxisSize: MainAxisSize.min,
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Text(
        "[Flutter必备]-Flex布局完全解读",
        style: littleStyle,
        maxLines: 2,
        overflow: TextOverflow.ellipsis,
      ),
      Padding(
        child: Text("也就是水平排放还是竖直排放,可以看出默认情况下都是主轴顶头,"
            "交叉轴居中比如horizontal下主轴为水平轴,交叉轴则为竖直。也就是水平顶头,竖直居中"
            "这里使用MultiShower快速展示,更好的对比出不同之处",
            style: infoStyle, maxLines: 2, overflow: TextOverflow.ellipsis),
        padding: EdgeInsets.only(top: 5),
      ),
    ],
  );

  var center = Row(//中间的部分
    children: <Widget>[
      Expanded(
          child: Padding(
        child: content,
        padding: EdgeInsets.all(5),
      )),
      ClipRRect(
        borderRadius: BorderRadius.all(Radius.circular(5)),
        child: Image.asset("images/wy_300x200.jpg",
          width: 80, height: 80, fit: BoxFit.cover),)
    ],
  );

  var end = Row(//底部
    children: <Widget>[
      Icon(
        Icons.grade,
        color: Colors.green,
        size: 20,
      ),
      Text(
        "1000W",
        style: infoStyle,
      ),
      Padding(child:Icon(Icons.tag_faces, color: Colors.lightBlueAccent, size: 20),
          padding: EdgeInsets.symmetric(horizontal: 5),),
      Text("2000W", style: infoStyle),
    ],
  );

  var result = Card(//总体拼合
      child: Container(
          height: 160,
          color: Colors.white,
          padding: EdgeInsets.all(10),
          child: Column(children: <Widget>[top, Expanded(child: center), end])));
  return result;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月20日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0.前言
  • 1.Flex的属性一览
  • 2.轴向:direction:Axis
  • 3.主轴方向:mainAxisAlignment:MainAxisAlignment
  • 4.交叉轴方向:crossAxisAlignment:CrossAxisAlignment
  • 5.主轴尺寸:mainAxisSize
  • 6.文字方向:textDirection:TextDirection
  • 7.竖直方向排序:verticalDirection:VerticalDirection
  • 8.基线对齐方式:textBaseline:TextBaseline
    • Expanded与Flex的搭配--- 更新于2019.1.22
    • 9.用Flex布局写个小例子
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档