Flutter Widget(2):单节点Widget

1.Padding

Padding作为基础控件,功能非常单一,给子节点设置padding属性。Flutter中并没有单独的Margin控件,在Container中有margin属性,实质上也是由Padding实现的。

 const Padding({
    Key key,
    @required this.padding,
    Widget child,
  }) : assert(padding != null),
       super(key: key, child: child);
  • padding:padding的类型为EdgeInsetsGeometry,EdgeInsetsGeometry是EdgeInsets以及EdgeInsetsDirectional的基类,一般都是使用EdgeInsets。

使用场景
如果在单一的间距场景,使用Padding比Container的成本要小一些,毕竟Container里面包含了多个widget。Padding能够实现的,Container都能够实现,只不过Container更加的复杂。

2.Align

设置child的对齐方式,例如居中、居左居右等,并根据child尺寸调节自身尺寸。Container中的align属性,也是使用Align去实现的。它能够实现的功能,Container都能实现。

 Align(
      alignment: Alignment.bottomRight,
      widthFactor: 5.0,
      heightFactor: 5.0,
      child: new Text("Align"),
)
  • alignment:对齐方式
  • widthFactor:宽度因子,如果设置的话,Align的宽度就是child的宽度乘以这个值,不能为负数。
  • heightFactor:高度因子,如果设置的话,Align的高度就是child的高度乘以这个值,不能为负数。

3.Center

Center继承自Align,只是将alignment设置为Alignment.center,其他属性和逻辑都与Align完全一样

class Center extends Align {
  /// Creates a widget that centers its child.
  const Center({ Key key, double widthFactor, double heightFactor, Widget child })
    : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}
        body: Container(
          child: Center(
            widthFactor: 5.0,
            heightFactor: 5.0,
            child: new Text("Align"),
          ),
        ),

4.FittedBox

FittedBox在自己的尺寸范围内缩放并且调整child的位置,与ImageView的ScaleType类似

  • 如果外部有约束的话,按照外部约束调整自身尺寸,然后缩放调整child,按照指定的条件进行布局;
  • 如果没有外部约束条件,则跟child尺寸一致,指定的缩放以及位置属性将不起作用。
          new Container(
            color: Colors.amberAccent,
            width: 300.0,
            height: 300.0,
            child: new FittedBox(
              fit: BoxFit.fill,
              alignment: Alignment.topLeft,
              child: new Container(
                color: Colors.red,
                child: new Text("FittedBox"),
              ),
            ),
          )

5.AspectRatio

AspectRatiode 的作用是调整child的宽高比,AspectRatio首先会在布局限制条件允许的范围内尽可能的扩展,widget的高度是由宽度和比率决定的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。

  • aspectRatio:宽与高的比例
          new Container(
            width: 360.0,
            child: new AspectRatio(
              aspectRatio:1.5,
              child: new Container(
                color: Colors.grey,
              ),
            ),
          )

6.ConstrainedBox

给child添加额外的约束条件,例如设置最小宽高,尽可能的占用区域等等

const BoxConstraints({
    this.minWidth = 0.0,
    this.maxWidth = double.infinity,
    this.minHeight = 0.0,
    this.maxHeight = double.infinity //最大值,尽可能占用区域
  });

7.UnconstrainedBox

不添加任何约束条件到child上,让child按照其原始的尺寸渲染。

8.BaseLine

根据child的baseline,来调整child的位置,比如让多个大小不一的Widget在同一水平线上

  • 如果child有baseline,则根据child的baseline属性,调整child的位置;
  • 如果child没有baseline,则根据child的bottom,来调整child的位置。
  • baseline:baseline数值,必须要有,从顶部算。
  • baselineType:bseline类型,也是必须要有的,目前有两种类型:
    • alphabetic:对齐字符底部的水平线;
    • ideographic:对齐表意字符的水平线。
          new Row(
            children: <Widget>[
              new Baseline(
                baseline: 100.0,
                baselineType: TextBaseline.alphabetic,
                child: new Text(
                  'TjTjTj',
                  style: new TextStyle(
                    fontSize: 20.0,
                    textBaseline: TextBaseline.alphabetic,
                  ),
                ),
              ),
              new Baseline(
                baseline:100.0,
                baselineType: TextBaseline.alphabetic,
                child: new Container(
                  width: 30.0,
                  height: 30.0,
                  color: Colors.grey,
                ),
              ),
              new Baseline(
                baseline: 100.0,
                baselineType: TextBaseline.alphabetic,
                child: new Text(
                  'RyRyRy',
                  style: new TextStyle(
                    fontSize: 35.0,
                    textBaseline: TextBaseline.alphabetic,
                  ),
                ),
              ),
            ],
          )

9.FractionallySizedBox

FractionallySizedBox控件会根据现有空间,来调整child的尺寸,child就算设置了具体的尺寸数值,也不起作用。

  • alignment:对齐方式,不能为null。
  • widthFactor:宽度因子
  • heightFactor:高度因子

当设置了具体的宽高因子,具体的宽高则根据现有空间宽高 * 因子,有可能会超出父控件的范围,当宽高因子大于1的时候;当没有设置宽高因子,则填满可用区域;

          new Container(
            color: Colors.blue,
            height: 200.0,
            width: 200.0,
            child: new FractionallySizedBox(
              alignment: Alignment.bottomLeft,
              widthFactor: 1.5,
              heightFactor: 0.5,
              child: new Container(
                color: Colors.red,
              ),
            ),
          )

10.IntrinsicHeight 和 IntrinsicWidth

这个控件的作用,是将可能高度宽度不受限制的child,调整到一个合适并且合理的尺寸,会存在效率问题,能别使用就尽量别使用。

11.LimitedBox

限定的最大高度或宽度,默认值是double.infinity,不能为负数。

    LimitedBox(
      maxWidth: 150.0,
      child: Container(
        color: Colors.blue,
        width: 250.0,
      ),
    ),

12.Offstage

一个布局widget,可以控制其子widget的显示和隐藏

  • 当offstage为true,当前控件不会被绘制在屏幕上,不会响应点击事件,也不会占用空间;
  • 当offstage为false,当前控件则跟平常用的控件一样渲染绘制
  new Offstage(
      offstage: false,
      child: Container(color: Colors.blue, height: 100.0),
    ),

13.OverflowBox

OverflowBox这个控件,允许child超出parent的范围显示

  • alignment:对齐方式。
  • minWidth:允许child的最小宽度。如果child宽度小于这个值,则按照最小宽度进行显示。
  • maxWidth:允许child的最大宽度。如果child宽度大于这个值,则按照最大宽度进行展示。
  • minHeight:允许child的最小高度。如果child高度小于这个值,则按照最小高度进行显示。
  • maxHeight:允许child的最大高度。如果child高度大于这个值,则按照最大高度进行展示。
Container(
            color: Colors.green,
            width: 100.0,
            height: 100.0,
            padding: const EdgeInsets.all(5.0),
            child: OverflowBox(
              alignment: Alignment.topLeft,
              maxWidth: 200.0,
              maxHeight: 400.0,
              child: Container(
                color: Color(0x33FFFFFF),
                width: 300.0,
                height: 300.0,
              ),
            ),
          )),

14.SizedBox

一个特定大小的盒子。这个widget强制它的孩子有一个特定的宽度和高度。如果宽度或高度为NULL,则此widget将调整自身大小以匹配该维度中的孩子的大小。

  • child不为null时,如果设置了宽高,则会强制把child尺寸调到此宽高;如果没有设置宽高,则会根据child尺寸进行调整;
  • child为null时,如果设置了宽高,则自身尺寸调整到此宽高值,如果没设置,则尺寸为0;
        Container(
            color: Colors.green,
            padding: const EdgeInsets.all(5.0),
            child: SizedBox(
              width: 200.0,
              height: 200.0,
              child: Container(
                color: Colors.red,
                width: 100.0,
                height: 300.0,
              ),
            ),
          )

15.SizedOverflowBox

一个具有特定大小的小部件,但将其原始约束传递给其子级,这可能会溢出。

  • 尺寸部分。通过将自身的固定尺寸,传递给child,来达到控制child尺寸的目的;
  • 超出部分。可以突破父节点尺寸的限制,超出部分也可以被渲染显示,与OverflowBox类似。

16.Transform

在绘制子widget之前应用转换的widget,平移、旋转、缩放都可以使用的到。如果只是单纯的进行变换的话,用Transform比用Container效率会更高。

const Transform({
  Key key,
  @required this.transform,
  this.origin,
  this.alignment,
  this.transformHitTests = true,
  Widget child,
})
  • transform:一个4x4的矩阵。
  • origin:旋转点,相对于左上角顶点的偏移。默认旋转点是左上角顶点。
  • alignment:相对于坐标系原点的对齐方式
  • transformHitTests:点击区域是否也做相应的改变。

另外三种构造函数

  • Transform.rotate:可以对子widget进行旋转变换
  • Transform.translate:接收一个offset参数,可以在绘制时沿x、y轴对子widget平移指定的距离。
  • Transform.scale:可以对子Widget进行缩小或放大

17.CustomSingleChildLayout

一个自定义的拥有单个子widget的布局widget,我们自定义一些单节点布局控件的时候,可以考虑使用它。

CustomSingleChildLayout提供了一个控制child布局的delegate,这个delegate可以控制这些因素:

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