TemperatureView 圓弧刻度溫度進度條

2021-07-24 19:32:29 字數 3366 閱讀 6980

temperatureview: 這是乙個自定義 view ,用來顯示溫度的變化過程。前段時間公司要做乙個實時監測機房溫度的應用,現在把這個溫度變化的 view 拿出來,自己對自定義 view 這方面的應用還不是很熟悉,這裡也算是對自己工作的乙個小總結。

二話不說,先上個效果圖:

當然,正常室溫變化是沒有這麼快的,再來張截圖:

下面來說說這個過程,首先可以將它分為幾個部分,分別為:

1、整個背景圓(可有可無)

2、進度弧(分為三段,顏色分別為綠黃紅)

3、進度弧上的文字(正常,預警,警告)

4、刻度弧(緊靠著進度弧內側的黑色弧)

5、刻度

6、中間的圓

7、指標

8、當前溫度

那些自定義屬性就不多說了,下面直接是繪製的過程(在此之前需要對繪製過程所用到的相關類有一定的了解)。

/**

* 背景圓

*@param canvas

*/private

void

drawoutcircle(canvas canvas)

msize:是控制項的大小,msize /2-dp2px(1):是讓這個背景圓和控制項有點距離。

/**

* 進度弧

*@param canvas

*/private

void

drawprogress(canvas canvas)

整個進度弧是從150度的位置開始到30度為止,也就是說整個進度弧所佔的角度為240度。將它分為40份(也就是最高40度的意思),所以剛好每份是6度。

給出的效果圖中進度弧是綠黃紅的,在這裡的繪製順序卻是綠紅黃,這是因為我想要將進度弧的兩端(綠和紅)設定為圓角,而黃色與綠色和紅色的銜接處為直角。如果在這裡的 paint 只是設定為paint.cap.round,那麼中間黃色部分和紅綠的銜接處也是圓角的;如果按照綠黃紅的順序來繪製,那麼黃色和紅色銜接處是圓角的,而綠色和黃色銜接處是直角的。其實很簡單,如果理解不了就動手試一下,保證瞬間明了。

/**

* 進度弧上的文字

*@param canvas

*/private

void

drawprogresstext(canvas canvas)

如果直接 drawtext ,那麼繪製的文字是水平的,想要把文字繪製在進度弧上,得先旋轉一定的角度。拿綠色這段弧來說:它佔了120度,所以中間位置是60度,那麼就需要旋轉60度了。

有一點要注意的是,綠色這段弧在左邊,所以要逆時針旋轉60度(旋轉角度為負數是逆時針,正數是順時針)。第二段弧上的文字為什麼旋轉了90度呢?它只需要旋轉30度就可以了啊?那是因為第一段弧時旋轉了-60度(逆時針),而第二段是從第一段的基礎上旋轉過來的,所以需要順時針旋轉90度。

/**

* 刻度弧

*@param canvas

*/private

void

drawscalearc(canvas canvas)

這裡只是簡單的畫條弧,只要注意半徑的把握就可以了。

// 旋轉的角度

float mangle = 240f / mtikecount;

// 畫右半部分的刻度

for (int i = 0; i <= mtikecount/2; i++) else

canvas.rotate(mangle, 0, 0);

}// 畫布回正

canvas.rotate(-mangle * mtikecount/2 - 6, 0, 0);

canvas.restore();

}

這裡只給出了右半部分的刻度,左半部分類似。繪製時先是旋轉角度(一共240度,分成40份,每次旋轉6度),然後再畫直線;畫直線時還要判斷如果是5的倍數,就畫長一點,並且標上刻度值,就是那些0,5,10,15…

這裡是右半部分,所以刻度值是從20開始,總共是20個刻度。最後要注意畫布回正

canvas.rotate(-mangle * mtikecount/2 - 6, 0, 0)

/**

* 中心圓

*@param canvas

*/private

void

drawinpoint(canvas canvas)

這個圓是為了凸顯接下來的指標更好看一些,這個圓的半徑就自行選擇咯。

/**

* 指標(這裡分為左右部分是為了畫出來的指標有立體感)

*@param canvas

*/private

void

drawpointer(canvas canvas)

其實指標部分可以一次性繪製完,但是為了看起來有點立體感,就將它分為左右兩部分,但是都是類似的。

就拿左半部分來說:首先將畫筆移動到中心圓的邊緣(leftpointerpath.moveto(pointradius/2, 0)),然後來個弧度是讓指標的根部為弧形的,接下來是指標的長度(長度=刻度弧的半徑(scalearcradius) - 長刻度的長度(mlongtikeheight) - 刻度值與刻度的間隔(dp2px(15)) - 尾部與刻度值的間隔(dp2px(offset))),最後再將它們連線起來。

指標上的圓意思是指標根部灰色的小圓,這樣看起來指標的根部是有個小洞的。

由於之前對這些 path 的操作不怎麼熟悉,所以在這裡花的時間較多,而且指標這部分所佔的篇幅也是蠻大的,因為難度也比較大嘛。

有興趣的可以來這學習鞏固下,這個系列都很給力:安卓自定義 view 高階 - path 基礎

/**

* 表盤上的文字

*@param canvas

*/private

void

drawpaneltext(canvas canvas)

這部分是表盤上顯示的當前溫度,首先是繪製「當前溫度」這四個字,然後在下方繪製具體的溫度值,注意好文字的位置就可以了,沒什麼難的。

到這裡繪製就結束了,整個表盤也就出來了。其實自定義乙個 view 最重要的是把它拆分為幾個部分,然後再一部分一部分的繪製出來,至於其中的某些計算部分就得靠自己的細心了,但是多試幾次還是可以出來的。

篇幅有限,只是拿出一些關鍵的**,有興趣可以來這看看原始碼,隨便 star 、fork github:

matplotlib 修改座標軸刻度值,刻度個數

主要是設定座標軸刻度值的數值特徵 例如為2 或 5 或 10 的倍數 以及 刻度值的文字格式 如 浮點型 或者 整型 這個是在工作中處理資料遇到的,系統自動預設的座標軸上的資料是浮點數,而我要求是整數 目前已解決 關鍵 from matplotlib.ticker import multiplelo...

關於求線段和線段,線段和圓弧,圓弧與圓弧的交點演算法

1 線段與線段求交點 已知線段的起點和終點,求交點,這個比較簡單,解2個二元一次方程可以求出。a 我這裡的演算法是判斷2條線段的定義域和值域是否有重合地方,有則進行下一步判斷,沒有這返回空,表示沒有交點。b 根據直線方程2點式y y1 y2 y1 x2 x1 x x1 進行解方程,不過這之前先進行對...

圓弧邊沿識別

boundary regionintersection,regionborder,inner 獲取區域邊沿 dilation circle regionborder,regiondilation,3.5 膨脹邊沿,作為亞畫素提取區域 union1 regiondilation,regionunion...