這是我參與8月更文挑戰的第9天,活動詳情檢視:8月更文挑戰
前言
我們都知道官方有很多的Widget供我們使用,但它提供的再多,也無法滿足產品和UI的需求, 當然,谷歌官方也肯定想到了這一點,所以在flutter中,也是支援自定義View的。
在Flutter中與繪製相關的是在Painting層次,具體見下圖:
這張Flutter架構圖我相信大家肯定在不同的文章中見過很多次了。
和Flutter自帶的Wdiget一樣,自定義的Widget也會經過Skia被編譯成原生程式碼,所以效能上也是不受影響的。
自定義View的流程
- 新建類繼承於CustomPainter實現paint()和shouldRepaint()方法
- 在paint方法中繪製你想要的內容
- 藉助於 CustomPaint Widget來構建自己的Widget
當然,上面僅僅是自定義的流程,具體的實現還是有很多細節需要處理的。
與繪製相關的知識
學過前端或者終端開發的童鞋,應該對繪製都比較熟悉,繪製主要還是靠畫布canvas和畫筆Paint和完成的,畫布就是你繪製圖形的地方,畫筆就是你用來作畫的筆。
畫布canvas
畫布是一個矩形區域,我們可以控制其每一畫素來繪製我們想要的內容
canvas 擁有多種繪製點、線、路徑、矩形、圓形、以及新增影像的方法,結合這些方法我們可以繪製出千變萬化的畫面。
雖然,畫布可以畫這些東西,但是決定這些圖形顏色、粗細表現的還是畫筆。
畫筆Paint
Paint非常好理解,就是我們用來畫圖形的工具,我們可以設定畫筆的顏色、粗細、是否抗鋸齒、筆觸形狀以及作畫風格。
通過這些屬性我們可以很方便的來定製自己的UI效果,當然我們在“作畫”的過程中可以定義多個畫筆,這樣更方便我們對圖形的繪製
Paint _paint = Paint()
..color = Colors.blueAccent //畫筆顏色
..strokeCap = StrokeCap.round //畫筆筆觸型別
..isAntiAlias = true //是否啟動抗鋸齒
..blendMode = BlendMode.exclusion //顏色混合模式
..style = PaintingStyle.fill //繪畫風格,預設為填充
..colorFilter = ColorFilter.mode(Colors.blueAccent,
BlendMode.exclusion) //顏色渲染模式,一般是矩陣效果來改變的,但是flutter中只能使用顏色混合模式
..maskFilter =
MaskFilter.blur(BlurStyle.inner, 3.0) //模糊遮罩效果,flutter中只有這個
..filterQuality = FilterQuality.high //顏色渲染模式的質量
..strokeWidth = 15.0 //畫筆的寬度
;
複製程式碼
Offset座標
這個就比較簡單,一般指得是在座標系中的一個點。
Offset(dx, dy)
複製程式碼
Rect
在圖形的繪製中,一般都是分割槽域繪製的,這個區域一般都是一個矩形,在繪製中通常使用Rect來儲存繪製的位置資訊。
當然,你可以指定Rect的上、下、左、右
- left : 矩形左邊的X座標
- top: 矩形頂部的Y座標
- right : 矩形右邊的X座標
- bottom: 矩形底部的Y座標
使用你這四個值就可以確定這個矩形的位置和大小。
當然,在一些平臺還會有Rect.fromCircle(Offset center, double radius)這個方法來構建矩形,其實想起來也是很簡單的,center就是圓心的座標,radius就是圓的半徑,由這兩個屬性構成圓的外切矩形就是我們需要的矩形。
Rect的多種構建方式:
fromPoints(Offset a, Offset b)
使用左上和右下角座標來確定矩形的大小和位置
fromCircle({ Offset center, double radius })
使用圓的圓心點座標和半徑和確定外切矩形的大小和位置
fromLTRB(double left, double top, double right, double bottom)
使用矩形左邊的X座標、矩形頂部的Y座標、矩形右邊的X座標、矩形底部的Y座標來確定矩形的大小和位置
fromLTWH(double left, double top, double width, double height)
使用矩形左邊的X座標、矩形頂部的Y座標矩形的寬高來確定矩形的大小和位置
複製程式碼
Flutter中的座標系
在Flutter中座標系的座標原點在左上角,X座標越往右越大,Y座標越往下越大 因為在View自定義過程中我們需要排放多個View,所以弄清楚這一點,在以後自定義Wdiget中會輕鬆很多。