官术网_书友最值得收藏!

3.2 基于Canvas和CustomPaint繪制表盤

有了前面理論知識的鋪墊,接下來正式開始擬物時鐘的開發實戰。首先創建一個新的工程,并修改lib/main.dart的代碼與3.1.1小節中的初始代碼相同。

本節進行表盤的繪制,表盤采用單獨的組件進行封裝。在lib下創建components目錄,用來容納項目中的組件,在components下創建ClockPanel.dart。

表盤由3部分組成,分別是外表盤、內表盤及表盤刻度。

3.2.1 使用Container繪制外表盤

外表盤基于Container組件實現,通過decoration設置形狀為原型,并通過多個BoxShadow設置新擬物的陰影效果

其中,ClockPanel的根布局是一個Stack組件,是一種層級布局組件,外表盤位于最底層,刻度位于最上層。在Stack的children屬性中,各個部分的布局都通過函數封裝起來,以提高代碼的清晰性和可讀性。getOuterPanel方法即繪制外表盤。ClockPanel接受一個size屬性,表示表盤的大小,在getOuterPanel中以size作為Container容器的大小。

回到lib/main.dart中對MyHomePage進行修改。將Scaffold的body組件替換為Stack,用于逐層擺放表盤與指針。同時將ClockPanel作為Stack的第一個元素。在build方法中,首先通過MediaQuery獲取到屏幕的寬高,并封裝為Size對象傳入ClockPanel。這里對寬高均乘以0.9的因子,在屏幕兩側留取余量,使其顯示更加美觀。具體代碼如下:

運行代碼,顯示效果如圖3-16所示,可以看出新擬物效果非常賞心悅目。

圖3-16 外表盤運行效果

3.2.2 使用Container繪制內表盤

外表盤通過Container的BoxShadow營造出凸起效果,內表盤則要營造出凹陷的效果。內表盤同樣也基于Container實現,主要通過BoxDecorationRadialGradient來設置漸變色。具體實現如下:

其中,getInnerPanel為內表盤繪制方法,內表盤由兩個Container通過Stack疊加而成。每個Container分別帶有一個漸變效果。兩個Container的長和寬再次乘以0.9的因子,作為表框的寬度。

運行代碼效果如圖3-17所示,可以看出表盤已經基本成型。

圖3-17 內表盤運行效果

3.2.3 使用CustomPaint繪制表盤刻度

完成表盤之后,接下來進行表盤刻度的繪制。有了刻度能夠更加精確地顯示時間。刻度通過CustomPaint組件繪制而成。

在ClockPanel中繼續創建一個getScale方法,用于繪制表盤刻度,代碼實現如下:

其中,ClockScalePainter類包含了刻度的具體繪制方法,接下來創建這個類。將ClockScale-Painter類的代碼寫在ClockPanel類之后即可。在ClockScalePainter的paint方法中,首先創建一個Paint畫筆,指定線條的顏色與粗細。之后通過canvas的drawLine方法進行畫線操作,根據12、3、6、9點的位置坐標進行畫線。代碼實現如下:

接下來,在ClockPanel類的build方法中,將getScale方法添加進去:

再次運行代碼,顯示效果如圖3-18所示。

圖3-18 表盤添加刻度后效果

至此,表盤部分開發完成。

主站蜘蛛池模板: 成安县| 广昌县| 达尔| 佛学| 讷河市| 河曲县| 普兰县| 青神县| 武安市| 德惠市| 黎川县| 获嘉县| 彰化县| 抚顺县| 道孚县| 巩义市| 房产| 西畴县| 合肥市| 彭泽县| 麻栗坡县| 堆龙德庆县| 札达县| 佳木斯市| 来凤县| 永嘉县| 铜山县| 玉门市| 永定县| 桓仁| 雷州市| 闵行区| 呼和浩特市| 无极县| 禹城市| 南安市| 读书| 喜德县| 宁远县| 溧水县| 鄂州市|