简介

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

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

Container的使用

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

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

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

  1. class Container extends StatelessWidget {
  2. Container({
  3. Key? key,
  4. this.alignment,
  5. this.padding,
  6. this.color,
  7. this.decoration,
  8. this.foregroundDecoration,
  9. double? width,
  10. double? height,
  11. BoxConstraints? constraints,
  12. this.margin,
  13. this.transform,
  14. this.transformAlignment,
  15. this.child,
  16. this.clipBehavior = Clip.none,
  17. })

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

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

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

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

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

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

  1. Widget build(BuildContext context) {
  2. return Container(
  3. decoration: const BoxDecoration(
  4. color: Colors.white,
  5. ),
  6. child: Column(
  7. children: [
  8. buildBoxRow(),
  9. buildBoxRow(),
  10. ],
  11. ),
  12. );
  13. }

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

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

  1. Widget buildBoxRow() => Row(
  2. textDirection: TextDirection.ltr,
  3. children: [
  4. Container(
  5. width: 100,
  6. child: Image.asset("images/head.jpg")
  7. )
  8. ],
  9. );

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

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

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

旋转Container

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

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

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

  1. Widget buildBoxRow() => Row(
  2. textDirection: TextDirection.ltr,
  3. children: [
  4. Container(
  5. transform: Matrix4.rotationZ(0.2),
  6. width: 100,
  7. child: Image.asset("images/head.jpg")
  8. )
  9. ],
  10. );

最后生成的APP如下:

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

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

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

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

比如下面的两个方法:

  1. /// Translation matrix.
  2. factory Matrix4.translation(Vector3 translation) => Matrix4.zero()
  3. ..setIdentity()
  4. ..setTranslation(translation);
  5. /// Translation matrix.
  6. factory Matrix4.translationValues(double x, double y, double z) =>
  7. Matrix4.zero()
  8. ..setIdentity()
  9. ..setTranslationRaw(x, y, z);

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

  1. /// Scale matrix.
  2. factory Matrix4.diagonal3Values(double x, double y, double z) =>
  3. Matrix4.zero()
  4. .._m4storage[15] = 1.0
  5. .._m4storage[10] = z
  6. .._m4storage[5] = y
  7. .._m4storage[0] = x;

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

Container中的BoxConstraints

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

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

  1. const BoxConstraints({
  2. this.minWidth = 0.0,
  3. this.maxWidth = double.infinity,
  4. this.minHeight = 0.0,
  5. this.maxHeight = double.infinity,
  6. }) : assert(minWidth != null),
  7. assert(maxWidth != null),
  8. assert(minHeight != null),
  9. assert(maxHeight != null);

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

  1. BoxConstraints.loose(Size size)
  2. BoxConstraints.tight(Size size)

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

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

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

  1. BoxConstraints.expand({double? width, double? height})

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

  1. const BoxConstraints.expand({
  2. double? width,
  3. double? height,
  4. }) : minWidth = width ?? double.infinity,
  5. maxWidth = width ?? double.infinity,
  6. minHeight = height ?? double.infinity,
  7. maxHeight = height ?? double.infinity;

总结

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

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

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

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

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

flutter系列之:flutter中常用的container layout详解的更多相关文章

  1. flutter系列之:flutter中常用的Stack layout详解

    [toc] 简介 对于现代APP的应用来说,为了更加美观,通常会需要用到不同图像的堆叠效果,比如在一个APP用户背景头像上面添加一个按钮,表示可以修改用户信息等. 要实现这样的效果,我们需要在一个Im ...

  2. flutter系列之:flutter中常用的GridView layout详解

    目录 简介 GridView详解 GridView的构造函数 GridView的使用 总结 简介 GridView是一个网格化的布局,如果在填充的过程中子组件超出了展示的范围的时候,那么GridVie ...

  3. flutter系列之:flutter中常用的ListView layout详解

    目录 简介 ListView详解 ListView中的特有属性 ListView的构造函数 ListView的使用 总结 简介 ListView是包含多个child组件的widget,在ListVie ...

  4. Android总结篇系列:Activity中几个主要函数详解

    Activity作为Android系统中四大基本组件之一,包含大量的与其他的各大组件.intent.widget以及系统各项服务等之间的交互的函数.在此,本文主要选取实际项目开发中常用的,但完全理解又 ...

  5. java日志框架系列(7):logback框架Layout详解

    1.Layout layout从字面意思来看就是排版.布局咯. 1.Layout简介 功能:负责把事件转换成字符串.Layout接口的格式化方法doLayout()负责将代表任何类型的事件的转换成一个 ...

  6. flutter系列之:构建Widget的上下文环境BuildContext详解

    目录 简介 BuildContext的本质 BuildContext和InheritedWidget BuildContext的层级关系 总结 简介 我们知道Flutter中有两种Widget,分别是 ...

  7. Windows学习总结(10)——Windows系统中常用的CMD命令详解

    1.ping命令 ping是电脑网络故障诊断中的常用的命令,它的作用是用来检查网络是否通畅或者网络连接速度.我们来看一下PING命令的具体表述. 日常的诊断过程中我们最常用到的就是诊断连接是否通畅. ...

  8. [ES6系列-03]ES6中关于参数相关特性详解(参数默认值与参数解构赋值与剩余参数)

    [原创] 码路工人 大家好,这里是码路工人有力量,我是码路工人,你们是力量. 今天总结一下 ES6 中跟参数相关的内容. 欢迎补充斧正.留言交流. 让我们互相学习一起进步. 1. ES6 参数默认值( ...

  9. Oracle中常用的to_char用法详解

    Oracle函数to_char转化数字型指定小数点位数的用法 to_char,函数功能,就是将数值型或者日期型转化为字符型. 比如最简单的应用: -- 1.0123=>1.0123 SELECT ...

随机推荐

  1. Python列表解析式的正确使用方式(一)

    先来逼逼两句: Python 是一种极其多样化和强大的编程语言!当需要解决一个问题时,它有着不同的方法.在本文中,将会展示列表解析式 (List Comprehension).我们将讨论如何使用它?什 ...

  2. NC20565 [SCOI2009]生日礼物

    NC20565 [SCOI2009]生日礼物 题目 题目描述 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有 \(N\) 个,分为 \(K\) 种.简单的说,可以将彩带考虑为 \(x\) ...

  3. .Net下极限生产力之efcore分表分库全自动化迁移CodeFirst

    .Net下极限生产力之分表分库全自动化Migrations Code-First ## 介绍 本文ShardinfCore版本x.6.x.x+ 本期主角: - [`ShardingCore`](htt ...

  4. 如何参与开源项目 - 细说 GitHub 上的 PR 全过程

    目录 一.概述 二.为什么要参与开源项目 三.为什么我想介绍如何 PR 四.我想参与开源项目,怎么开始? 4.1.寻找一个合适的开源项目 4.2.寻找贡献点 五.我要提交 PR,怎么上手? 5.1.第 ...

  5. Host–Parasite(主从关系): Graph LSTM-in-LSTM for Group Activity Recognition

    This article aims to tackle the problem of group activity recognition in the multiple-person scene. ...

  6. 零基础学Java(8)数组

    数组 数组存储相同类型值的序列. 声明数组 数组是一种数据结构,用来存储同一类型值的集合.通过一个整型下标(index,或称索引)可以访问数组中的每一个值.例如,如果a是一个整型数组,a[i]就是数组 ...

  7. JUC源码学习笔记2——AQS共享和Semaphore,CountDownLatch

    本文主要讲述AQS的共享模式,共享和独占具有类似的套路,所以如果你不清楚AQS的独占的话,可以看我的<JUC源码学习笔记1> 主要参考内容有<Java并发编程的艺术>,< ...

  8. Redis_

    Redis学习 Redis学习(一) 1. NoSQL的引言 NoSQL(Not Only SQL ),意即不仅仅是SQL, 泛指非关系型的数据库.Nosql这个技术门类,早期就有人提出,发展至200 ...

  9. tokitsukaze and Soldier 来源:牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28886/1004 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K, ...

  10. MD5,Des,RSA加密解密

    一.加密和解密 下面先熟悉几个概念 1>对称加密:加密的key和解密的key是同一个 但是如何确保密钥安全地进行传递?秘钥的安全是一个问题 2>非对称加密:加密点的key和解密的key不是 ...