到目前為止,Flutter 已經提供了 30 多種不同的 Widget 用於組合構建檢視。
但對於一些複雜的檢視,用 SDK 提供的這些 Widget 仍然無法組合出來 ? 。
我們必須自己繪製這些檢視,就像在 Android 中使用 Canvas 和 Paint 來進行繪製那樣 ? 。
在 Flutter 中,當然也有可以讓你自由繪製的方案,他就是 CustomPaint。
CustomPaint
CustomPaint 也是一個 Widget。
你可把它嵌到檢視樹的任意一個節點位置。
先看看它的常用屬性:
屬性 | 型別 | 說明 |
---|---|---|
painter | CustomPainter | 背景畫筆,繪製內容會顯示在child子節點後面 |
foregroundPainter | CustomPainter | 前景畫筆,繪製內容會顯示在child子節點前面 |
size | Size | 設定繪製區域的大小。如果有child,則忽略該引數,且繪製區域為child的尺寸 |
isComplex | bool | 是否複雜的繪製,如果是,Flutter會應用一些快取策略來減少重複渲染的開銷。預設false |
willChange | bool | 和isComplex配合使用,當啟用快取時,該屬性代表在下一幀中繪製是否會改變。預設false |
child | Widget | 沒錯,CustomPaint是可以包含一個子節點的 |
從 CustomPaint 的屬性可以看出,實際繪製是通過 CustomPainter 來完成的。
以 child 為基準,CustomPainter 分為兩個部分,一個是繪製在 child 上面的 pinter
,一個是繪製在 child 下面的 foregroundPainter
。
? 看個例子:
CustomPaint(
isComplex: true,
willChange: true,
size: Size(deviceSize.width, deviceSize.height),
painter: GamePainter(background, maliao, position),
foregroundPainter: ForegroundGamePainter(),
)
複製程式碼
馬良神筆 CustomPainter
CustomPainter 是一個抽象類,你需要繼承它實現自己的邏輯。
class MyPainter extends CustomPainter {
@override
paint(Canvas canvas, Size size) {
...
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
複製程式碼
繼承 CustomPainter 最重要的是實現 paint(Canvas canvas, Size size)
和 shouldRepaint(CustomPainter oldDelegate)
這兩個函式。
paint()
中是繪製邏輯,可以在這獲得畫布 Canvas 和 畫布的大小 Size。shouldRepaint()
返回 true 才會進行重繪,否則就只會繪製一次。你可以通過一些條件判斷來決定是否每次繪製,這樣能夠節約系統資源。
實現 CustomPainter 最重要的就是在 paint()
中寫繪製邏輯。
? 一個例子:
class MyPainter extends CustomPainter {
@override
void paint(ui.Canvas canvas, ui.Size size) {
Paint paint = Paint()
..isAntiAlias = true
..color = Colors.blueAccent
..strokeWidth = 10
..style = PaintingStyle.fill;
canvas.drawLine(Offset(10, 10), Offset(250, 250), paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
複製程式碼
? 看看效果:
在繪製過程中,有兩個重要的角色:Paint 和 Canvas。
Paint
Paint 是畫筆,在 Canvas 上作畫就是依靠它去 "執行" 的。
看看 Paint 有那些常用屬性:
屬性 | 型別 | 說明 |
---|---|---|
isAntiAlias | bool | 是否開啟抗鋸齒,開啟抗鋸齒能夠是邊緣平滑,當然也更消耗系統資源 |
color | Color | 顏色 |
colorFilter | ColorFilter | 會對顏色進行變換 |
filterQuality | FilterQuality | 設定繪製的影像質量 |
invertColors | bool | 是否使用反向顏色。繪製圖片時也能夠反轉圖片的顏色 |
maskFilter | MaskFilter | 設定遮罩效果。比如高斯模糊 |
shader | Shader | 漸變顏色。會覆蓋color |
strokeCap | StrokeCap | 設定繪製形狀的邊緣風格。如圓角、方形等 |
strokeJoin | StrokeJoin | 設定兩個繪製形狀銜接處的風格。如圓角、方形等 |
strokeWidth | double | 畫筆的寬度 |
style | PaintingStyle | 填充方式。PaintingStyle.fill-充滿;PaintingStyle.stroke-空心 |
blendMode | BlendMode | 畫素混合模式。當畫一個shape或者合成圖層的時候會生效。 |
以上就是 Paint 常用的屬性,你可以都試試看看效果。
這是一段 Paint 的配置程式碼:
Paint paint = Paint()
..isAntiAlias = true
..color = Colors.redAccent
..strokeWidth = 10
..style = PaintingStyle.fill
..filterQuality = FilterQuality.high
..strokeCap = StrokeCap.round
..strokeJoin = StrokeJoin.round
..maskFilter = MaskFilter.blur(BlurStyle.normal, 50)
..invertColors = false
..blendMode = BlendMode.color
..shader = ui.Gradient.linear(
Offset(0, 0), Offset(100, 100), [Colors.red, Colors.blueAccent])
複製程式碼
Canvas
Canvas 作為畫布,它和在 Android 使用的 Canvas 在很多介面上很像。
它包含了很多基礎的繪製操作,通過組合這些基礎的繪製操作,可以繪製出幾乎任何的檢視。
Canvas 的操作主要有兩類:
針對 Canvas 的變換操作,如平移、旋轉、縮放、圖層等操作。
繪製基礎圖形的操作,如線段、路徑、圖片、幾何圖形等。
Canvas 的這些操作後續再詳細講解 ?。