写点什么

flutter 系列之:flutter 中常用的 container layout 详解

作者:程序那些事
  • 2022 年 6 月 11 日
  • 本文字数:2629 字

    阅读完需:约 9 分钟

简介

在上一篇文章中,我们列举了 flutter 中的所有 layout 类,并且详细介绍了两个非常常用的 layout:Row 和 Column。


掌握了上面两个基本的 layout 还是不够的,如果需要应付日常的 layout 使用,我们还需要掌握多一些 layout 组件。今天我们会介绍一个功能强大的 layout:Container layout。

Container 的使用

Container 是一个空白的容器,通常可以用 Container 来封装其他的 widget。那么为什么还需要把 widget 封装在 Container 中呢?这是因为 Container 中包含了一些特殊的功能。


比如 Container 中可以设置背景颜色或者背景图片,并且可以设置 padding, margins 和 borders。这就为组件的自定义提供了诸多空间。


首先看一下 Container 的定义和构造函数:


class Container extends StatelessWidget {  Container({    Key? key,    this.alignment,    this.padding,    this.color,    this.decoration,    this.foregroundDecoration,    double? width,    double? height,    BoxConstraints? constraints,    this.margin,    this.transform,    this.transformAlignment,    this.child,    this.clipBehavior = Clip.none,  })
复制代码


可以看到 Container 是一个 StatelessWidget,它的构造函数可以传入多个非常有用的属性,用来控制 Container 的表现。


Container 中有 padding,decoration,constraints 和 margin 这些和位置相关的一些属性,他们有什么关系呢?


container 首先将 child 用 padding 包裹起来,padding 可以用 decoration 进行填充。


填充后的 padding 又可以应用 constraints 来进行限制(比如 width 和 height),然后这个组件又可以使用 margin 空白包裹起来。


接下来我们看一个简单的 Container 中包含 Column 和 Row 的例子。


首先构造一个 container widget,它包含一个 Column:


  Widget build(BuildContext context) {    return Container(      decoration: const BoxDecoration(        color: Colors.white,      ),      child: Column(        children: [          buildBoxRow(),          buildBoxRow(),        ],      ),    );  }
复制代码


这里给 Container 设置了一个 BoxDecoration,用于指定 Container 的背景颜色。


在 Child 中给定了一个 Column widget,它的 child 是一个 Row 对象。


  Widget buildBoxRow()  => Row(    textDirection: TextDirection.ltr,    children: [      Container(        width: 100,        child: Image.asset("images/head.jpg")      )    ],  );
复制代码


这里的 Row 中又是一个包含了 Image 的 Container 对象。


最后运行,我们可以得到下面的界面:



Container 中包含两行,每行包含一个 Image 对象。

旋转 Container

默认情况下 Container 是一个正常布局的 widget,但是有时候我们可能需要实现一些特殊效果,比如说组件的旋转,Container 提供的 transform 属性可以很方便的做到这一点。


对于 Container 来说,transform 是在组件绘制中最先被应用的,transform 之后会进行 decoration 的绘制,然后进行 child 的绘制,最后进行 foregroundDecoration 的绘制。


还是上面的例子,我们试一下 transform 属性是如何工作的,我们在包含 image 的 container 中加入 transform 属性:


  Widget buildBoxRow()  => Row(    textDirection: TextDirection.ltr,    children: [      Container(          transform: Matrix4.rotationZ(0.2),        width: 100,        child: Image.asset("images/head.jpg")      )    ],  );
复制代码


最后生成的 APP 如下:



可以看到图片已经沿 Z 轴进行了旋转。


这里的旋转使用的是 Matrix4.rotationZ,也就是沿 Z 轴选择,当然你可以可以使用 rotationX 或者 rotationY,分别沿 X 轴或者 Y 轴旋转。


如果选择 rotationX,那么看起来的图像应该是这样的:



事实上,Matrix4 不仅仅可以沿单独的轴进行旋转,还可以选择特定的向量方向进行选择。


比如下面的两个方法:


  /// Translation matrix.  factory Matrix4.translation(Vector3 translation) => Matrix4.zero()    ..setIdentity()    ..setTranslation(translation);
/// Translation matrix. factory Matrix4.translationValues(double x, double y, double z) => Matrix4.zero() ..setIdentity() ..setTranslationRaw(x, y, z);
复制代码


Matrix4 还可以沿三个方向进行进行放大缩写,如下面的方法:


  /// Scale matrix.  factory Matrix4.diagonal3Values(double x, double y, double z) =>      Matrix4.zero()        .._m4storage[15] = 1.0        .._m4storage[10] = z        .._m4storage[5] = y        .._m4storage[0] = x;
复制代码


感兴趣的朋友可以自行尝试。

Container 中的 BoxConstraints

在 Container 中设置 Constraints 的时候,我们使用的是 BoxConstraints。BoxConstraints 有四个包含数字的属性,分别是 minWidth,maxWidth,minHeight 和 maxHeight。


所以 BoxConstraints 提供了这四个值的构造函数:


  const BoxConstraints({    this.minWidth = 0.0,    this.maxWidth = double.infinity,    this.minHeight = 0.0,    this.maxHeight = double.infinity,  }) : assert(minWidth != null),       assert(maxWidth != null),       assert(minHeight != null),       assert(maxHeight != null);
复制代码


BoxConstraints 还有两个构造函数分别是 loose 和 tight:


BoxConstraints.loose(Size size) BoxConstraints.tight(Size size) 
复制代码


这两个有什么区别呢?如果一个 axis 的最小值是 0 的话,那么这个 BoxConstraints 就是 loose。


如果一个 axis 的最大值和最小值是相等的情况,那么这个 BoxConstraints 就是 tight。


BoxConstraints 中还有一个非常常用的方法如下:


 BoxConstraints.expand({double? width, double? height}) 
复制代码


expand 的意思就是最大值和最小值都是 infinity 的,具体的定义可以从方法的实现中看出:


  const BoxConstraints.expand({    double? width,    double? height,  }) : minWidth = width ?? double.infinity,       maxWidth = width ?? double.infinity,       minHeight = height ?? double.infinity,       maxHeight = height ?? double.infinity;
复制代码

总结

Container 是一个非常常用的 layout 组件,大家可以熟练的使用起来。


本文的例子:https://github.com/ddean2009/learn-flutter.git


更多内容请参考 http://www.flydean.com/08-flutter-ui-layout-container/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 刚刚阅读数: 4
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
flutter系列之:flutter中常用的container layout详解_flutter_程序那些事_InfoQ写作社区