Flutter之Container用法详解

最近开始接触Flutter,网上对Flutter评价很高,加上是谷歌这种大公司研发推广的,决定先入坑。

废话不多说,直奔主题!学习框架,首先要将里面常用控件熟练使用,后面可以逐步深入、究其原理。

前言

相关文章:Flutter学习目录

github地址:Flutter学习

文章结构

  • Color Property
  • Child Property
  • Alignment Property
  • Constraints Property
  • Margin Property
  • Padding Property
  • Decoration Property
  • ForegroundDecoration Property
  • Transform Property

介绍

Container类似于iOS中的UIView,具有绘制定位调整大小功能。通常用来装载其它子控件,假如Container没有子控件,它将自动填充整个屏幕;反之,会根据子控件大小,调整自身大小,从而达到自适应效果。

注意:

使用Container时,通常要有一个父控件,一般情况下不单独使用Container。常用的父控件有Center widget、Padding Widget、Column Widget、Row Widget、Scaffold Widget。

一、Color Property

这个属性用于设置Container的背景颜色,类似于iOS中的UIView的backgroundColor。使用如下:

  • Colors Class
//Container颜色属性之Colors
class Color_Property_Colors extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
          //color: Colors.green,//正常颜色
          //color:Colors.green[200],//带有阴影(相当于是透明度)
          color: Colors.green.shade200,//同上
        ),
    );
  }
}

呈现效果如下:


图1 Container之Colors属性
  • Color Class
//Container颜色属性之Color
class Color_Property_Color extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        //color: Color(0xFFFFFFFF),//一定是8位,否则报错
        //color: Color.fromARGB(255, 66, 165, 245),
        color: Color.fromRGBO(66, 165, 245, 1.0),//作用同上
      ),
    );
  }
}

呈现效果如下:


图2 Container之Color属性
注意:

1、使用8位16进制而不是6位
2、.fromARGB含义
A = Alpha or opacity, R = Red, G = Green, B = Blue
3、.fromRGBO含义
R = Red, G = Green, B = Blue, O = Opacity

二、Child Property

如前言所述,如果Container里面没有子控件,它就会填充整个屏幕;如果有子控件,Container就会自动适应子控件大小
另外,Container只能容纳一个子控件,如果想容纳更多的子控件,可以将子控件设置为Row、Column、Stack(这三个子控件都有一个children属性)

  • 添加子控件
//Container属性之Child
class Child_Property extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromRGBO(66, 165, 245, 1.0),
        child: Text("Flutter Cheatsheet"),
      ),
    );
  }
}

呈现效果如下:


图3 添加子控件

三、Alignment Property

Alignment属性主要是针对于Container内部的子控件布局。
主要有以下几个属性:Alignment、FractionalOffset、AlignmentDirectional

  • Alignment
    代码如下:
//Container属性之Alignment
class Alignment_Property extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        child: Text("Flutter Cheatsheet",
             style: TextStyle(
               fontSize: 30.0
             ),
        ),
        //不加这句话,Container会自适应child大小;加上以后会充满屏幕
        //alignment: Alignment(0.0, 0.0),
        alignment: Alignment.center,//等价于上面
      ),
    );
  }
}

效果如下:


图4 Container属性之Alignment

Alignment坐标系图如下:


图5 Alignment坐标系

常用等价属性:
Alignment.bottomCenter 对应 Alignment(0.0, 1.0)
Alignment.bottomLeft 对应 Alignment(-1.0, 1.0)
Alignment.bottomRight 对应 Alignment(1.0, 1.0)
Alignment.center 对应 Alignment(0.0, 0.0)
Alignment.centerLeft 对应 Alignment(-1.0, 0.0)
Alignment.centerRight 对应 Alignment(1.0, 0.0)
Alignment.topCenter 对应 Alignment(0.0, -1.0)
Alignment.topLeft 对应 Alignment(-1.0, -1.0)
Alignment.topRight 对应 Alignment(1.0, -1.0)

  • FractionalOffset
    这个属性跟上面讲的Alignment非常相似,唯一的不同就是坐标系:
    Alignment坐标系是X:-1.0--1.0;Y:-1.0--1.0,
    FractionalOffset坐标系是X:0.0--1.0,Y:0.0--1.0。

FractionalOffset坐标系图如下:

图6 FractionalOffset坐标系

代码如下:

//Container属性之FractionalOffset
class Alignment_FractionalOffset extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        child: Text("Flutter Cheatsheet",
          style: TextStyle(
              fontSize: 30.0
          ),
        ),
        //不加这句话,Container会自适应child大小;加上以后会充满屏幕
        //alignment: FractionalOffset(0.5, 0.5),
        alignment: FractionalOffset.center,//等价于上面
      ),
    );
  }
}

常用等价属性如下
FractionalOffset.bottomCenter 对应 FractionalOffset(0.5, 1.0)
FractionalOffset.bottomLeft 对应 FractionalOffset(0.0, 1.0)
FractionalOffset.bottomRight 对应 FractionalOffset(1.0, 1.0)
FractionalOffset.center 对应 FractionalOffset(0.5, 0.5)
FractionalOffset.centerLeft 对应 FractionalOffset(0.0, 0.5)
FractionalOffset.centerRight 对应 FractionalOffset(1.0, 0.5)
FractionalOffset.topCenter 对应 FractionalOffset(0.5, 0.0)
FractionalOffset.topLeft 对应 FractionalOffset(0.0, 0.0)
FractionalOffset.topRight 对应 FractionalOffset(1.0, 0.0)

  • AlignmentDirectional
    说到这个属性,就要提到一个小插曲:
    网上说AlignmentDirectional有2个坐标系,是因为TextDirection.ltr和TextDirection.rtl,但是经过本人的亲身实验,这种观点是不对的,不知道是不是由于官方官方框架更新的原。
    最终结论:这个属性跟Alignment用法是完全一样(既然完全一样,何必多此一举呢?)。

坐标系图如下:


图7 AlignmentDirectional坐标系

代码如下:

//Container属性之AlignmentDirectional
class Alignment_AlignmentDirectional extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        child: Text("Flutter",
          style: TextStyle(
              fontSize: 15.0
          ),
          //textDirection: TextDirection.ltr,//正常,从左向右(不影响alignment)
          textDirection: TextDirection.ltr,//从右向左(不影响alignment)
        ),
        //不加这句话,Container会自适应child大小;加上以后会充满屏幕
        alignment:AlignmentDirectional(-1.0, 1.0),
        //alignment: AlignmentDirectional.bottomStart,//等价于上面
      ),
    );
  }
}

常用等价属性:
AlignmentDirectional.bottomCenter 对应 AlignmentDirectional(0.0, 1.0)
AlignmentDirectional.bottomEnd 对应 AlignmentDirectional(1.0, 1.0)
AlignmentDirectional.bottomStart 对应 AlignmentDirectional(-1.0, 1.0)
AlignmentDirectional.center 对应 AlignmentDirectional(0.0, 0.0)
AlignmentDirectional.centerEnd 对应 AlignmentDirectional(1.0, 0.0)
AlignmentDirectional.centerStart 对应 AlignmentDirectional(-1.0, 0.0)
AlignmentDirectional.topCenter 对应 AlignmentDirectional(0.0, -1.0)
AlignmentDirectional.topEnd 对应 AlignmentDirectional(1.0, -1.0)
AlignmentDirectional.topStart 对应 AlignmentDirectional(-1.0, -1.0)

四、Constraints Property

布局属性,主要讲的是怎么确定控件的大小;其中经常使用的就是BoxConstraint。BoxConstraint包含minWidth、maxWidth、minHeight、maxHeight,详细介绍如下:

  • Container无子控件(场景1)
    代码如下:
//Container属性之Constraints Property
class Constraints_Property extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          constraints: BoxConstraints(
            maxHeight: 300,
            maxWidth: 200,
            minWidth: 150,
            minHeight: 150,
          ),
        ),
      ),
    );
  }
}

呈现效果如下:


图8 Container之Constraints无子控件

前面说过如果Container没有子控件,Container将填充整个屏幕,但是这里设置maxHeight、maxWidth。

  • Container有子控件(场景2)
    代码如下:
//Container属性之Constraints(有子控件)
class Constraints_Property_HasChild extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          child: Text("Flutter"),
          constraints: BoxConstraints(
            maxHeight: 300,
            maxWidth: 200,
            minWidth: 150,
            minHeight: 150,
          ),
        ),
      ),
    );
  }
}

呈现效果如下:


图9 Container之Constraints有子控件

这里虽然有一个子控件,Container会调整自身大小来适应内部子控件,但是由于设置了min-width和min-height。所以Container不会完全和子控件一样大,除非子控件尺寸大于min-width和min-height。

尝试更改子控件大小,代码如下:

//Container属性之Constraints(有子控件)
class Constraints_Property_HasChild extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          //child: Text("Flutter"),
          child: Text("Flutter Cheatsheet Flutter Cheatsheet"),
          constraints: BoxConstraints(
            maxHeight: 300,
            maxWidth: 200,
            minWidth: 150,
            minHeight: 150,
          ),
        ),
      ),
    );
  }
}

呈现效果图如下:


图10 Container之Constraints有子控件

从上面这张图可以看出Container不能超出max-width和max-height。

  • Container有子控件(场景3)
    当Container有子控件,我们想让Container不去适应子控件,而是充满整个屏幕或父控件,怎么办?
    答案就是使用BoxConstraints.expand()。
    代码如下:
//Container属性之Constraints(有子控件、充满整个屏幕)
class Constraints_Property_HasChild_AllScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          //child: Text("Flutter"),
          child: Text("Flutter"),
          constraints: BoxConstraints.expand(),
        ),
      ),
    );
  }
} 

呈现效果如下:


图11 Container之Constraints有子控件

此时发现Container是充满整个屏幕的,我们也可以限制充满屏幕大小,比如说1/2宽、1/3高等。

五、Margin Property

跟前端的css类似,这个Margin指的是相邻控件之间的距离,主要是用EdgeInsets。

  • EdgeInsets.all()
  • EdgeInsets.symmetric()
  • EdgeInsets.fromLTRB()
  • EdgeInsets.only()

详细如下:

  • EdgeInsets.all()
    代码如下:
//EdgeInsets.all()
class Margin_Property_EdgeInsets_all extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          margin: EdgeInsets.all(20.0),
        ),
      ),
    );
  }
}

呈现效果如下:


图12 Margin之EdgeInsets.all
  • EdgeInsets.symmetric()
    这个主要用于添加垂直和水平方向上的约束。
    代码如下:
//EdgeInsets.symmetric()
class Margin_Property_EdgeInsets_symmetric extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          margin: EdgeInsets.symmetric(
            vertical: 20.0,
            horizontal: 50.0,
          ),
        ),
      ),
    );
  }
}

呈现效果如下:


图13 Margin之EdgeInsets. symmetric
  • EdgeInsets.fromLTRB()
    这个主要设置left, top, right,bottom边距。
    代码如下:
//EdgeInsets.fromLTRB()
class Margin_Property_EdgeInsets_fromLTRB extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          color: Colors.green,
          margin: EdgeInsets.fromLTRB(20.0, 30.0, 40.0, 50.0)
        ),
      ),
    );
  }
}

呈现效果:


图14 Margin之EdgeInsets. fromLTRB
  • EdgeInsets.only()
    用于设置哪些是非零的,不设置默认是零。
    代码如下:
//EdgeInsets.only()
class Margin_Property_EdgeInsets_only extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
            color: Colors.green,
            margin: EdgeInsets.only(
              left: 20.0,
              bottom: 40.0,
              top: 50.0,
            )
        ),
      ),
    );
  }
}

呈现效果如下:


图15 Margin之EdgeInsets.only

六、Padding Property

这个用于设置主控件内部子控件之间的间距。和Margin一样,利用到EdgeInsets。
代码如下:

//EdgeInsets.all
class Padding_Property_EdgeInsets_all extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Color.fromARGB(255, 66, 165, 245),
        alignment: AlignmentDirectional(0.0, 0.0),
        child: Container(
          margin: EdgeInsets.only(
            left: 20.0,
            bottom: 40.0,
            top: 50.0,
          ),
          padding: EdgeInsets.all(10.0),//设置内部Text控件边距
          color: Colors.green,
          child: Text("Flutter Cheatsheet"),
          //不设置这个Container和子控件一样大小、这样margin设置也就没有意义了
          constraints: BoxConstraints.expand(),
        ),
      ),
    );
  }
}

呈现效果如下:


图16 Padding之EdgeInsets.all

七、Decoration Property

  • BoxDecoration Class
  • FlutterLogoDecoration Class
  • ShapeDecoration Class
  • UnderlineTabIndicator Class
    由于涉及篇幅较长,后续会重新文章详细讲解,敬请关注。

八、ForegroundDecoration Property

  • BoxDecoration Class
  • FlutterLogoDecoration Class
  • ShapeDecoration Class
  • UnderlineTabIndicator Class
    由于涉及篇幅较长,后续会重新文章详细讲解,敬请关注

九、Transform Property

在Container属性中添加transform属性,并使用Matrix类设置transform的值,即可达到各种变换效果,代码如下:

//Transform Property
class Transform_Property extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Color.fromARGB(255, 66, 165, 245),
      alignment: AlignmentDirectional(0.0, 0.0),
      child: Container(
        padding: EdgeInsets.all(40.0),
        color: Colors.green,
        child: Text("Flutter Cheatsheet"),  
        transform: Matrix4.rotationZ(0.5),
      ),
    );
  }
}

效果图如下:


图17 Transform Property

参考文章:

Flutter — Container Cheat Sheet

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容