大家都知道 Flutter 是一套 UI 框架,透過 dart:ui 與底層 API 互動,最終呈現在手機螢幕上或接收點擊事件。使用的時候,都是透過已經定義好的 Widget 決定畫面,並不會直接與 dart:ui 互動。但是實際上,我們也是可以跳過 Widget,直接操作 dart:ui 的 API 來幫我們畫出我們想樣的畫面
而 Widget、 Element、RenderObject 等等我們比較常互動的物件,則更多是讓我們更方面的使用 Flutter,讓我們可以輕鬆在畫面畫出想要的結果,而不用自己一筆一劃決定,也不需要自己決定何時重新渲染畫面。
畫一個圓
下面這段代碼直接操作 Picture、Scene、Window ...等物件,在畫面上畫出一個藍色的原型。
- 一開始創建了 PictureRecorder 與 Canvas,並利用 Paint 在 Canvas 上畫出一個圓,與在 CustomPainter 畫圖的做法相當類似。
- 當畫完之後,呼叫 PictureRecording.endRecording(),並取得一張 Picture
- 接著我們就能把這張 Picture 透過 SceneBuilder 放進 Scene 中
- 最後用 window 來這一幀的畫面
dart
void main() {
PictureRecorder recorder = PictureRecorder();
Canvas canvas = Canvas(recorder);
Paint circlePaint = Paint();
circlePaint.color = Colors.blue;
canvas.drawCircle(Offset(400, 400), 300, circlePaint);
Picture picture = recorder.endRecording();
SceneBuilder sceneBuilder = SceneBuilder();
sceneBuilder.addPicture(Offset(0, 0), picture);
Scene scene = sceneBuilder.build();
window.onDrawFrame = () {
window.render(scene);
};
window.scheduleFrame();
} 當執行上面這段代碼後,我們在畫面上看到一個藍色圓形,向下方左圖一樣。同樣的方法也可以用來畫出向下方右圖那樣的複雜圖形。
小結
雖然我們可以直接使用 dart:ui 在畫面上直接作畫,但實際上在絕大多數的狀況下不會這麼做,目前我自己也想不到一樣狀況會需要這樣做。畢竟除了繪製,Flutter 實際上還做了許許多多事,不管是狀態管理或者是效能優化,透過 Widget、Element 和 RenderObject 去操作還是推薦的做法。