Flutter 硬核入门之Container
本系列教程基于Flutter widget, 意在为Flutter 入门提供基础建设. 重点在讲解widget 的用法,参数以及扩展.同时会加入对源码的阅读思考,做到知其然知其所以然.
适宜人群: 入门
以下教程基于:
- Flutter 版本: stable, 3.0.5
- dart sdk 版本: >=2.15.0 <3.0.0
Container
介绍
接触过Flutter 的小伙伴应该都清楚, Container 作为基础控件. 应该是使用频率最高的控件之一, 本系列教程也是从Container 开始着手.
Container 是一个StatelessWidget, 这里我们应该敏锐的意识到, Container 本身并不负责状态变化管理, 我们从它的build方法也可以看到, 它最终返回的Widget 是由本身参数来构建相应的widget. Container只作为一个容器去承载相应的widget. 给予相应的变化.
用法
width\height 以及 constraints
constraints 是一个约束属性, 而width\height 用于描述组件的宽高. 为什么把这几个参数放在一起讲呢? 实际上width\height 最终也会转换成constraints .
1 | constraints = |
当width\height 有一者不为null的时候, 都转换成constraints . 而constraints 最终会约束着Container 的大小. 如果constraints 也为null ,则会有两种情况:
- 没有child:
当没有child 的时候, 会自行创建一个LimitedBox来限制自身的宽高. - 有child:
当有child 的时候,最终会走child 的约束.1
2
3
4
5
6
7if (child == null && (constraints == null || !constraints!.isTight)) {
current = LimitedBox(
maxWidth: 0.0,
maxHeight: 0.0,
child: ConstrainedBox(constraints: const BoxConstraints.expand()),
);
}
alignment
alignment 用来描述组件内部child 相对于父组件的位置. 在Container 中, 如果没有child , 并且约束为空或者约束不是tight 时. alignment 属性都不会生效.
1 | if (child == null && (constraints == null || !constraints!.isTight)) { |
示例:
1 | // 1.生效的 |
第一个不用解释, 它是可以居中的
第二个它不生效的原因是没有child
第三个没有生效的原因是它的constraints 并不是tight 约束
padding\margin
padding\margin 是内边距和外边距, 但是实现和原理上它都是Padding 组件实现的, 唯一不同的是padding 将会先添加, 而margin 会在增加颜色、裁切、Decorated之后才会去添加. 所以最后的显示上, paddign会在内部而margin在外部.
clipBehavior
clipBehavior 不为none的时候可以裁剪超出Container 限制范围的布局, 它的作用原理还是来源于ClipPath , Container 默认提供了一个_DecorationClipper .它会根据用户提供的decoration 变化而裁切自身.
1 | @override |
这里的Offset.zero & size 等同于 Rect.fromLTWH(offset.x, offset.y, size.width, size.height), 也就是在这个矩形范围内进行裁切.常用于child 为 Stack、CustomPainter ,CustomSingleChildLayout 等布局的时候.
decoration
用于Container 的装饰, 这里我们通常使用BoxDecoration、ShapeDecoration 当作装饰盒. 这里可以使用图片或者绘制阴影等等. 我们也可以自定义创建Decoration.
1 | // ShapeDecoration 示例 |
transform\transformAlignment
transform 是对child 进行矩阵变换, 而transformAlignment 则是对矩阵变幻定义原点
1 | Container( |
这里作示例的变换就是将当前图层沿x轴往内旋转60度, 绕z轴逆时针旋转45度.结果如图:
总结
从上面分析的结果看来, Container确实只是一个容器组件. 本身是由其他组件叠加最后反映出来的结果. 我们去构建一个widget 的时候, 也可以参考这种思路, 把每个交互的构成拆分、细化再合成. 这也符合单一原则, 方便我们后期做维护.
结语
这里是WeninerIo,热爱生活且热爱旅行.如果你对这次的分享感兴趣又或者有什么疑惑, 不妨评论区留言 + 关注.期待下一次更好的相遇.