## Transform变换
Transform可以在其子Widget绘制时对其应用一个矩阵变换(transformation),Matrix4是一个4D矩阵,通过它我们可以实现各种矩阵操作。下面是一个例子:
```
Container(
color: Colors.black,
child: new Transform(
alignment: Alignment.topRight, //相对于坐标系原点的对齐方式
transform: new Matrix4.skewY(0.3), //沿Y轴倾斜0.3弧度
child: new Container(
padding: const EdgeInsets.all(8.0),
color: Colors.deepOrange,
child: const Text('Apartment for rent!'),
),
),
);
```
![](https://box.kancloud.cn/62f0e5d6e466dd57b955c2967883c360_460x154.png)
关于矩阵变换的相关内容属于线性代数范畴,本书不做讨论,读者有兴趣可以自行了解。本书中,我们把焦点放在Flutter中一些常见的变换效果上。
### 平移
Transform.translate接收一个offset参数,可以在绘制时沿x、y轴对子widget平移指定的距离。
```
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
//默认原点为左上角,左移20像素,向上平移5像素
child: Transform.translate(offset: Offset(-20.0, -5.0),
child: Text("Hello world"),
),
)
```
效果:
![](https://box.kancloud.cn/0d09b047ddce387a53e59ddc22101e61_292x62.png)
### 旋转
Transform.rotate可以对子widget进行旋转变换,如:
```
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
child: Transform.rotate(
//旋转90度
angle:math.pi/2 ,
child: Text("Hello world"),
),
);
```
> 注意:要使用math.pi需先进行如下导包。
>
>
> ```
> import 'dart:math' as math;
>
> ```
效果:
![](https://box.kancloud.cn/bd59a490af5ff8c7fad6b5c0cc08ce5a_250x122.png)
### 缩放
Transform.scale可以对子Widget进行缩小或放大,如:
```
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
child: Transform.scale(
scale: 1.5, //放大到1.5倍
child: Text("Hello world")
)
);
```
效果:
![](https://box.kancloud.cn/c2a7138ed85d8c24cf00d29552bdfd8a_212x72.png)
### 注意
- Transform的变换是应用在绘制阶段,而并不是应用在布局(layout)阶段,所以无论对子widget应用何种变化,其占用空间的大小和在屏幕上的位置都是固定不变的,因为这些是在布局阶段就确定的。下面我们具体说明:
```
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
child: Transform.scale(scale: 1.5,
child: Text("Hello world")
)
),
Text("你好", style: TextStyle(color: Colors.green, fontSize: 18.0),)
],
)
```
显示效果:
![](https://box.kancloud.cn/8c035a7c8d8dd0599449ef101c38706b_294x72.png)
由于第一个Text应用变换(放大)后,其在绘制时会放大,但其占用的空间依然为红色部分,所以第二个text会紧挨着红色部分,最终就会出现文字有重合部分。
- 由于矩阵变化只会作用在绘制阶段,所以在某些场景下,在UI需要变化时,可以直接通过矩阵变化来达到视觉上的UI改变,而不需要去重新触发build流程,这样会节省layout的开销,所以性能会比较好。如之前介绍的Flow widget,它内部就是用矩阵变换来更新UI,除此之外,Flutter的动画widget中也大量使用了Transform以提高性能。
### RotatedBox
RotatedBox和Transform.rotate功能相似,它们都可以对子widget进行旋转变换,但是有一点不同:RotatedBox的变换是在layout阶段,会影响在子widget的位置和大小。我们将上面介绍Transform.rotate时的示例改一下:
```
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
//将Transform.rotate换成RotatedBox
child: RotatedBox(
quarterTurns: 1, //旋转90度(1/4圈)
child: Text("Hello world"),
),
),
Text("你好", style: TextStyle(color: Colors.green, fontSize: 18.0),)
],
),
```
效果:
![](https://box.kancloud.cn/e9cad6b60d8a1fa1d0cc71a749fcafe8_314x132.png)
由于RotatedBox是作用于layout阶段,所以widget会旋转90度(而不只是绘制的内容),decoration会作用到widget所占用的实际空间上,所以就是上图的效果。读者可以和前面Transform.rotate示例对比理解。
- 缘起
- 起步
- 移动开发技术简介
- Flutter简介
- 搭建Flutter开发环境
- 常见配置问题
- Dart语言简介
- 第一个Flutter应用
- 计数器示例
- 路由管理
- 包管理
- 资源管理
- 调试Flutter APP
- Dart线程模型及异常捕获
- 基础Widgets
- Widget简介
- 文本、字体样式
- 按钮
- 图片和Icon
- 单选框和复选框
- 输入框和表单
- 布局类Widgets
- 布局类Widgets简介
- 线性布局Row、Column
- 弹性布局Flex
- 流式布局Wrap、Flow
- 层叠布局Stack、Positioned
- 容器类Widgets
- Padding
- 布局限制类容器ConstrainedBox、SizeBox
- 装饰容器DecoratedBox
- 变换Transform
- Container容器
- Scaffold、TabBar、底部导航
- 可滚动Widgets
- 可滚动Widgets简介
- SingleChildScrollView
- ListView
- GridView
- CustomScrollView
- 滚动监听及控制ScrollController
- 功能型Widgets
- 导航返回拦截-WillPopScope
- 数据共享-InheritedWidget
- 主题-Theme
- 事件处理与通知
- 原始指针事件处理
- 手势识别
- 全局事件总线
- 通知Notification
- 动画
- Flutter动画简介
- 动画结构
- 自定义路由过渡动画
- Hero动画
- 交错动画
- 自定义Widget
- 自定义Widget方法简介
- 通过组合现有Widget实现
- 实例:TurnBox
- CustomPaint与Canvas
- 实例:圆形渐变进度条(自绘)
- 文件操作与网络请求
- 文件操作
- Http请求-HttpClient
- Http请求-Dio package
- 实例:Http分块下载
- WebSocket
- 使用Socket API
- Json转Model
- 包与插件
- 开发package
- 插件开发:平台通道简介
- 插件开发:实现Android端API
- 插件开发:实现IOS端API
- 系统能力调用
- 国际化
- 让App支持多语言
- 实现Localizations
- 使用Intl包
- Flutter核心原理
- Flutter UI系统
- Element和BuildContext
- RenderObject与RenderBox
- Flutter从启动到显示