Loading

【Flutter】容器类组件之变换

前言

Transform可以在其子组件绘制时对其应用一些矩阵变换来实现一些特效。

接口描述

const Transform({
    Key key,
    @required this.transform,
    this.origin,
    this.alignment,
    this.transformHitTests = true,
    Widget child,
  }) : assert(transform != null),
       super(key: key, child: child);

代码示例

// 变换(Transform)
// Transform可以在其子组件绘制时对其应用一些矩阵变换来实现一些特效。

import 'dart:math' as math;
import 'package:flutter/material.dart';

class TransformTest extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('变换'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[

            // 4D矩阵
            Container(
              color: Colors.black,
              child: Transform(
                // 相对于坐标系原点的对齐方式
                alignment: Alignment.topRight,
                // Matrix4是一个4D矩阵。沿Y轴倾斜0.3弧度
                transform: Matrix4.skewY(0.3),
                child: Container(
                  padding: EdgeInsets.all(8.0),
                  color: Colors.deepOrange,
                  child: Text('Transform'),
                ),
              ),
            ),

            // 平移
            DecoratedBox(
              decoration: BoxDecoration(color: Colors.red),
              // 接收一个offset参数,可以在绘制时沿x、y轴对子组件平移指定的距离
              child: Transform.translate(offset: Offset(-20.0, -5.0), child: Text('Transform.'),),
            ),

            // 旋转
            DecoratedBox(
              decoration: BoxDecoration(color: Colors.red),
              child: Transform.rotate(angle: math.pi/2, child: Text('Transform.'),),
            ),

            // 缩放
            DecoratedBox(
              decoration: BoxDecoration(color: Colors.red),
               child: Transform.scale(scale: 5, child: Text('Transform.'),),
            ),

            // 验证变换原理
            Text("你好", style: TextStyle(color: Colors.green, fontSize: 18.0),),

            // RotatedBox
            // RotatedBox和Transform.rotate功能相似,它们都可以对子组件进行旋转变换,
            // 但是有一点不同:RotatedBox的变换是在layout阶段,会影响在子组件的位置和大小。
            DecoratedBox(
              decoration: BoxDecoration(color: Colors.red),
              // 将Transform.rotate换成RotatedBox
              child: RotatedBox(
                // 旋转90度,四分之一圈
                quarterTurns: 1,
                child: Text('Transform.'),
              ),
            ),
            Text("你好", style: TextStyle(color: Colors.green, fontSize: 18.0),),

          ],
        ),

      ),
    );
  }
}

总结

Transform的变换是应用在绘制阶段,而并不是应用在布局阶段,所以无论对子组件应用何种变化,其占用空间的大小和在屏幕的位置是固定不变的,因为这些是在布局阶段就确定的。
由于矩阵变化只会作用在绘制阶段,所以在某些场景下,在UI需要变化时,可以通过矩阵变化来达到视觉上UI改变,而不需要重新触发build流程,这样会节省layout的开销,所以性能会比较好。
由于RotatedBox是作用于layout阶段,所以子组件会旋转90度(而不只是绘制的内容),decoration会作用到子组件所占用的实际空间上。

posted @ 2019-12-30 15:04  Parzulpan  阅读(745)  评论(0编辑  收藏  举报