Android 畫乙個 iPhone 樣式的小時鐘

2021-07-25 11:01:34 字數 3172 閱讀 6213

iphone主介面的時鐘幾乎每天都會看到,某天突發奇想,用android是否也可以畫乙個類似的呢?於是決定也嘗試著畫乙個,順便鞏固下自繪控制項的知識,請看

做一件事情先要在腦海中想清楚,仔細觀察了下iphone的這個時鐘(以畫圖的方式來考慮),其實很簡單,大概分析如下:

背景是乙個黑色的圓角矩形

表盤是乙個白色的正圓,且半徑稍小於背景圓角矩形寬一半

表盤中間是乙個小正圓來顯示指標的軸

表盤內圈為1-12的數字,且每個數字的角度間隔為30度(360/12=30)

時針、分鐘、秒針分別是粗細、長度、顏色不同的線段,且從中心點放射出

既然大概的思路有了,那麼就要去思考接下來可能需要用到的api

重寫onmeasure函式,說明請移步測量初步

繪圖api的使用(畫圓角矩形、圓、線段、文字)函式的說明請移步2d繪圖初步

正弦和余弦(計算指標、表盤數字的終點座標)

角度與弧度的換算(由於sin和cos函式需要的引數為「弧度」而不是「角度」,所以需要將角度轉換為弧度)

角度轉換為弧度該怎麼轉換呢,我們知道1弧度的弧的長度=半徑長度,並且圓周長(這裡解釋成全部弧長和360度更好理解)為2πr,也就是說360度的弧長為2πr,180度的弧長為πr,那弧度呢?,當然是πr/r=π啦,那假設60度呢?也就是π/(180/60),可以轉換為π*60/180,也就是轉換公式啦,當然系統為我們提供了直接轉換的函式,我們就偷下懶啦,其實該函式內部演算法也是用了這個公式,有興趣的朋友可以點開看下。

繪製指標起點座標為表盤中心點,但是根據時間不一樣,終點座標是會變化的,那麼這個終點座標該怎麼求呢?請先看下圖:

假設我們的指標正好指向2點鐘,此時半徑r與垂直中心線的夾角為60度,那麼此時指標與圓的切點p(x,y)也就是我們所要的終點座標,這個終點座標便是(px,py),只要我們求出,px的水平距離+a(圓心水平距離),py的垂直距離+b(圓心垂直距離)便得到了終點座標,這時候就去要用到sin函式(對邊與斜邊的比)和cos函式(鄰邊與斜邊的比)啦,以半徑r為斜邊,px的距離便是sin60*r,py的距離cos60*r,再加上圓心距離,便得到2點鐘的終點座標,其實情況以此類推。

測量自身大小

private int measurewidth(int widthmeasurespec)  else if (mode == measurespec.at_most) 

return result;

}private int measureheight(int heightmeasurespec) else if (mode == measurespec.at_most)

return result;

}

計算中心座標點

//計算圓心座標

private float computecenterpoint()

畫黑色圓角矩形背景

//畫表外邊框

private void drawclockboundborder(canvas canvas)

畫半徑稍小於背景圓角矩形寬一半的白色正圓

//畫表盤

private void drawclockroundborder(canvas canvas)

畫指標的軸,即黑色小圓

//畫表盤中心軸

private void drawclockcenterpoint(canvas canvas)

畫表盤數字

//畫表盤數字

private void drawclocknumber(canvas canvas)

}

畫指標

//畫時分秒指標

private void drawclockallpointer(canvas canvas)

//畫時針指標

private void drawclockhourpointer(float angle, canvas canvas)

//畫分針指標

private void drawclockminutepointer(float angle, canvas canvas)

//畫秒針指標

private void drawclocksecondpointer(float angle, canvas canvas)

//根據角度、指標長度 計算出起始座標

private float computepointerpoint(float angle, float pointerlenght) else if (angle <= 180f) else if (angle <= 270f) else if (angle <= 360f)

return linepoints;

}

讓時鐘開始工作

public void startclockwork()  catch (interruptedexception e) }}

}).start();

}public void stopclockwork()

@override

protected void onattachedtowindow()

@override

protected void ondetachedfromwindow()

最執行效果如下:

以上**沒有做太多的優化,請見諒,其中一些重複的計算可以優化的,還有就是在想在ondraw的時候如何只單獨繪製三根指標,避免繪製不會實時更改的區域,還在研究當中。

如有描述不當、錯誤請指正,謝謝。

使用Android來畫乙個鐘錶

今天我們來畫乙個android鐘錶,只不過沒有美化,看起來有點粗糙.功能實現就好啦 效果圖 具體思路 我們首先使用canvas.drawoval來畫乙個圓 計算圓的中心,記住圓的中心等於 x 寬 2 y 高 2 如果有移位的加上移位就能計算出圓的中心點 核心的系統方法 canvas.drawoval...

CSS 畫乙個心

效果圖 實現原理 可以把這個心分為兩部分,兩個長方形,分別設定 border radius,transform rotate 設定屬性之後 再次新增乙個,設定相反的 rotate 設定其中乙個的 left 值 就成了 為了看起來有立體感,可以設定左邊的 box shadow cssbodydivdi...

CSS 畫乙個心

效果圖 實現原理 可以把這個心分為兩部分,兩個長方形,分別設定 border radius,transform rotate 設定屬性之後 再次新增乙個,設定相反的 rotate 設定其中乙個的 left 值 就成了 為了看起來有立體感,可以設定左邊的 box shadow cssbodydivdi...