android自定義時(shí)鐘

? ? 關(guān)于android自定義時(shí)鐘網(wǎng)上已經(jīng)有很多了,百度一下“android自定義時(shí)鐘”能看到很多大佬們自定義的時(shí)鐘,思路大致都差不多,所以在這里像記錄一下自己實(shí)現(xiàn)時(shí)鐘的過程!先看一下效果圖:


然后整理一下實(shí)現(xiàn)步驟:①、畫出圓形表盤②、畫出表盤刻度畫出和表盤數(shù)字③根據(jù)當(dāng)前時(shí)間畫出時(shí)分秒指針④、讓時(shí)分秒指針動(dòng)起來。

1、畫出表盤:

? ? 新建一個(gè)項(xiàng)目->新建一個(gè)類叫Clock集成View這個(gè)父類實(shí)現(xiàn)兩個(gè)構(gòu)造方法并在構(gòu)造方法中新增init()方法主要是用來初始化表盤畫筆可以設(shè)置盤表的粗細(xì)、顏色、樣式等等。

現(xiàn)在屏幕上隨便找一個(gè)(PAN_CENTER_POSITION_X, PAN_CENTER_POSITION_Y)坐標(biāo)指定表盤圓心所在的位置并聲明一個(gè)圓盤半徑(PAN_RADIUS)的變量,實(shí)現(xiàn)View父類中onDraw(Canvas canvas)方法,這個(gè)方法會提供一個(gè)Canvas(畫布),使用這個(gè)類我們可以畫出我們想要的圖形,上面提到的畫筆(Paint)這個(gè)類可以讓我們實(shí)現(xiàn)什么樣子的圖形,使用canvas中的畫圓形方法畫出表盤:canvas.drawCircle(PAN_CENTER_POSITION_X, PAN_CENTER_POSITION_Y, PAN_RADIUS, panPaint);

2、畫出表盤刻度:

在畫表盤刻度之前先看一張圖計(jì)算一下每一個(gè)刻度開始坐標(biāo)和和結(jié)束坐標(biāo):

一個(gè)表盤上有60個(gè)指針,指針轉(zhuǎn)一圈是360°就是說相鄰刻度之間的夾角是6°,這時(shí)候以表盤圓心作為原點(diǎn)做坐標(biāo)系每個(gè)刻度和Y軸的正半軸之間夾角就是6°*第n個(gè)刻度,那么刻度相對于圓心的坐標(biāo)就是(圓的半徑*sin(6°*第n個(gè)刻度),圓的半徑*cos(6°*第n個(gè)刻度)),用1點(diǎn)為例:他和12點(diǎn)之間的夾角是30°也就是5*6°,那么從上面的圖可以看出來,1點(diǎn)在屏幕上的坐標(biāo)就是(圓心X軸坐標(biāo)+半徑*sin30°,圓心Y軸坐標(biāo)-半徑*cos30°),這個(gè)就是刻度的起始位置。那么結(jié)束位置(方向需要指向圓心)也就是圖中的P點(diǎn)就好計(jì)算了,刻度長短需要我們自己指定,P點(diǎn)的在屏幕上的坐標(biāo)和1點(diǎn)的坐標(biāo)計(jì)算方法一樣只是需要用(半徑-P1)的長度,加一個(gè)循環(huán)畫出刻度:

注意使用Math.sin和Math.cos方法時(shí)入?yún)⑹腔¢L并不是度數(shù),所以我們需要使用Math.toRadians方法將數(shù)字轉(zhuǎn)化為度數(shù)。

每循環(huán)5次就是小時(shí)(1,2,3.....)的刻度 ,我們需要把他區(qū)分出來用來后續(xù)在表盤上刻畫上數(shù)字,為了區(qū)分普通刻度和特殊的刻度,每五次就是修改畫筆的屬性并增加了刻度的長度,現(xiàn)在把注釋放開實(shí)現(xiàn)的效果:

至于畫出的表盤的數(shù)字就簡單了,說白了就是把刻度的長度延長一點(diǎn)就是數(shù)字所在的位置,也是就刻度的結(jié)束點(diǎn)的坐標(biāo),和P點(diǎn)在同一條直線上在加上一些微調(diào),所以文字就很好畫了:

3、根據(jù)當(dāng)前時(shí)間畫出時(shí)分秒指針:

? ? 對于畫三個(gè)指針也可以參照畫刻度的思路,其實(shí)都是調(diào)用drawline()方法,只是開始、結(jié)束位置不同,指針的開始位置就是圓心在屏幕上的坐標(biāo)這個(gè)很好理解,而結(jié)束位置其實(shí)就是P點(diǎn)當(dāng)然了我們不能讓最長秒針和P點(diǎn)重合,所以我們需要指定三個(gè)花邊Paint和三個(gè)指針的長度分別代表時(shí)分秒的長度,我是用Caledar這個(gè)類獲取當(dāng)前的時(shí)分秒時(shí)間,獲取這個(gè)時(shí)間主要是用來計(jì)算出三個(gè)秒針的結(jié)束為止,說白了就是計(jì)算出他們與12點(diǎn)這個(gè)位置夾角大小:

秒針和分針與12點(diǎn)之間的夾角大小就是當(dāng)前的時(shí)分*6°,而時(shí)針不同:當(dāng)前的小時(shí)*6°*5因?yàn)榕c12點(diǎn)中間夾雜了4個(gè)刻度,而且時(shí)間必須要重新獲取Calendar實(shí)例去獲取。否則獲取一直是同一個(gè)時(shí)間

把代碼放開就是下面的效果:

4、讓時(shí)分秒指針動(dòng)起來:

? ? 其實(shí)只要調(diào)用postInvalidateDelayed(1000)這個(gè)api就是成,他表示每隔多長時(shí)間重新繪制一次,但是話又說回來了這樣比較浪費(fèi),所有的東西都要重新繪制一次這是沒必要的,也可以使用定時(shí)器或者h(yuǎn)andler每隔多少時(shí)間繪制一次時(shí)分秒針即可,有興趣的同學(xué)可以嘗試一下。

5、自定義屬性:

? ? 一般我們自己創(chuàng)建了一個(gè)自定義View就想著自定義View里面不能讓他都是死的啊,我可以在xml里面定義他的先關(guān)屬性例如:我想在xml中指定他的半徑。只要在sytle.xml文件中定義如下屬性:

相當(dāng)于一個(gè)名叫radius里面有個(gè)float類型的radius屬性

在自定義View中含有AttributeSet的構(gòu)造函數(shù)中獲取自定義的屬性:

獲取屬性值key值是:style名稱_屬性名稱,用完需要回收

在xml中就可以使用我們自定義的屬性了:

好了結(jié)束!有什么錯(cuò)誤的地方歡迎指正!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容