Transform可以在其子組件繪制時對其應(yīng)用一些矩陣變換來實現(xiàn)一些特效阿逃。Matrix4是一個4D矩陣卧波,通過它我們可以實現(xiàn)各種矩陣操作时肿,下面是一個例子:
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!'),
),
),
);
運行效果如圖5-10所示:
關(guān)于矩陣變換的相關(guān)內(nèi)容屬于線性代數(shù)范疇,本書不做討論港粱,讀者有興趣可以自行了解螃成。本書中,我們把焦點放在Flutter中一些常見的變換效果上查坪。另外寸宏,由于矩陣變化時發(fā)生在繪制時,而無需重新布局和構(gòu)建等過程偿曙,所以性能很好氮凝。
#平移
Transform.translate接收一個offset參數(shù),可以在繪制時沿x望忆、y軸對子組件平移指定的距離罩阵。
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
//默認原點為左上角,左移20像素启摄,向上平移5像素
child: Transform.translate(
offset: Offset(-20.0, -5.0),
child: Text("Hello world"),
),
)
效果如圖5-11所示:
#旋轉(zhuǎn)
Transform.rotate可以對子組件進行旋轉(zhuǎn)變換稿壁,如:
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
child: Transform.rotate(
//旋轉(zhuǎn)90度
angle:math.pi/2 ,
child: Text("Hello world"),
),
);
注意:要使用math.pi需先進行如下導(dǎo)包歉备。
import 'dart:math' as math;
效果如圖5-12所示:
#縮放
Transform.scale可以對子組件進行縮小或放大傅是,如:
DecoratedBox(
decoration:BoxDecoration(color: Colors.red),
child: Transform.scale(
scale: 1.5, //放大到1.5倍
child: Text("Hello world")
)
);
效果如圖5-13所示:
#注意
-
Transform的變換是應(yīng)用在繪制階段,而并不是應(yīng)用在布局(layout)階段,所以無論對子組件應(yīng)用何種變化喧笔,其占用空間的大小和在屏幕上的位置都是固定不變的帽驯,因為這些是在布局階段就確定的。下面我們具體說明:
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),)
],
)
運行效果如圖5-14所示:
由于第一個Text應(yīng)用變換(放大)后书闸,其在繪制時會放大尼变,但其占用的空間依然為紅色部分,所以第二個Text會緊挨著紅色部分梗劫,最終就會出現(xiàn)文字重合享甸。
由于矩陣變化只會作用在繪制階段,所以在某些場景下梳侨,在UI需要變化時蛉威,可以直接通過矩陣變化來達到視覺上的UI改變,而不需要去重新觸發(fā)build流程走哺,這樣會節(jié)省layout的開銷蚯嫌,所以性能會比較好。如之前介紹的Flow組件丙躏,它內(nèi)部就是用矩陣變換來更新UI择示,除此之外,F(xiàn)lutter的動畫組件中也大量使用了Transform以提高性能晒旅。
思考題:使用Transform對其子組件先進行平移然后再旋轉(zhuǎn)和先旋轉(zhuǎn)再平移栅盲,兩者最終的效果一樣嗎?為什么废恋?
#RotatedBox
RotatedBox和Transform.rotate功能相似谈秫,它們都可以對子組件進行旋轉(zhuǎn)變換,但是有一點不同:RotatedBox的變換是在layout階段鱼鼓,會影響在子組件的位置和大小拟烫。我們將上面介紹Transform.rotate時的示例改一下:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
//將Transform.rotate換成RotatedBox
child: RotatedBox(
quarterTurns: 1, //旋轉(zhuǎn)90度(1/4圈)
child: Text("Hello world"),
),
),
Text("你好", style: TextStyle(color: Colors.green, fontSize: 18.0),)
],
),
效果如圖5-15所示:
由于RotatedBox是作用于layout階段,所以子組件會旋轉(zhuǎn)90度(而不只是繪制的內(nèi)容)迄本,decoration會作用到子組件所占用的實際空間上硕淑,所以最終就是上圖的效果,讀者可以和前面Transform.rotate示例對比理解嘉赎。