Android 自定義 View 實戰之角度選擇器

2021-09-11 13:21:33 字數 3512 閱讀 3335

本文比較基礎,在閱讀本文前只需要掌握最基礎的自定義view知識和android事件知識。

有一天晚上,在google photos檢視**,用了一下它的剪裁功能,於是我馬上就被其介面和操作吸引。

第二天我就想模仿做乙個這樣的裁相簿,當然,我做了。同時也做了乙個和google photos裁圖頁面幾乎一模一樣的角度選擇器。那麼,來看一下最終的效果:

仔細觀察這個效果,先分析構成結構,我把它分成三部分:

表示刻度的點

相應點上方的數字

控制項**的當前刻度與三角

可以看出,構成元素十分簡單,不涉及,drawable,那麼只需要用canvas畫出來就好了。

接下來觀察手勢的操作,檢視隨著手指滑動,控制項做出的變化,這裡的變化有:

手指按上去時,部分區域變亮(部分區域即為可見區域)

隨著手指滑動,相應的數字發生移動,當前角度值也發生改變

離中心越近,透明度越低,且的下方的點要大一些

好了,我們對這個控制項已經分析的很透徹了,根據分析,首先我們要在viewondraw()方法中畫出構成元素,之後要讓它動起來,在ontouchevent()方法中監聽手勢,改變一些值並重繪我們的view,這裡很明顯,我們要改變的肯定是當前角度這個值。

既然有了思路,那麼就要馬上動手,不然下次忘記掉了怎麼辦?

畫點首先,先把點給畫出來,位置很簡單,肯定是從檢視中心開始畫,往左往右分別畫點。

for (int i = 0; i < mpointcount; i++) 複製**
其中mpointcount為所要畫的點個數,這裡預設為51個,mpointmargin為兩點間的邊距,長度為view的寬度除以點的個數。

看看效果

嗯,成功的把點給畫出來了。

畫刻度上方的數字

既然把點給畫出來了,根據我們的思路,我們要把數字給畫到正確的位置上,畫數字當然很簡單,這裡難的是找到正確的位置。

首先,我們的數字是會移動的,隨著當前角度的不同,所展示的數字大小位置都不同。但毫無疑問的是,這個位置(x座標)肯定是關於當前角度的乙個函式。至於具體是乙個什麼樣的函式,相信聰明的你很快就可以分析出來,畢竟只是乙個線性關係,這裡就直接貼**了。

private

void

drawdegreetext

(int degrees, canvas canvas, boolean canreach)

}複製**

按照我們的效果,我們需要畫出-90°~90°的刻度,其中-45°~45°是可到達角度,另外的角度不可到達。

drawdegreetext(0, canvas, true);

drawdegreetext(15, canvas, true);

drawdegreetext(30, canvas, true);

drawdegreetext(45, canvas, true);

drawdegreetext(-15, canvas, true);

drawdegreetext(-30, canvas, true);

drawdegreetext(-45, canvas, true);

drawdegreetext(60, canvas, false);

drawdegreetext(75, canvas, false);

drawdegreetext(90, canvas, false);

drawdegreetext(-60, canvas, false);

drawdegreetext(-75, canvas, false);

drawdegreetext(-90, canvas, false);複製**

好了,來看一下效果,可以看到,數字被畫在了正確的位置。

畫當前角度

這個超級簡單呢,位置也特別好確定,上方三角形的path也非常好知道,但是這裡要注意的是,當當前角度為0°左右時,不應該把0°刻度顯示出來。

//畫當前角度

if (mcurrentdegrees >= 10) else

if (mcurrentdegrees <= -10) else

if (mcurrentdegrees < 0) else

//三角指示器的path

mindicatorpath.moveto(w / 2, h / 2 + mfontmetrics.top / 2 - 18);

mindicatorpath.rlineto(-8, -8);

mindicatorpath.rlineto(16, 0);複製**

還有乙個小細節,就是離中心越近,其透明度越來越低,也就是說,我們要根據離中心的位置,來改變畫筆paintalpha值,再將點畫出。

for (int i = 0; i < mpointcount; i++)  else 

if (i > mpointcount / 2 - 8 && i < mpointcount / 2 + 8

&& i > zeroindex - 22 && i < zeroindex + 22)

……}複製**

這時,已經很像了,只是還不能動。

動起來該繪製的部分我們已經都繪製起來了,是時候讓這個view動起來了,角度選擇器的觸控事件不複雜,我們只需要在我們移動手指的時候根據滑動距離來改變當前角度值並重繪檢視就可以看到移動效果了。為什麼呢?因為我們之前在畫數字的時候,位置都是由當前角度這個值決定的,所以它一發生變化,數字的位置也會發生改變。

@override

public

boolean

ontouchevent

(motionevent event)

break;}……

return

true;

}private

void

onscrollevent

(motionevent event, float distance)

}複製**

當然你還需要處理一些細節性的東西,比如在數字移動的時候,靠近中心一定範圍就會消失(透明度變為0),這些都是很容易控制的,只要改變畫筆的透明度就好了,但是正是對細節的把控,才能做出乙個效果讓使用者滿意的自定義view。最後,再來看一下效果。

擴充套件到這裡,我們做的角度選擇器已經和google photos的幾乎一模一樣了,但是,僅僅這樣就夠了。不,不夠,我們還要繼續擴充套件,為什麼只能達到正負45°,我們要所有的範圍自由選擇,也就是-180°~180°,然後數字顏色啊,點的顏色啊都要讓人自由選擇。所以我們要擴充套件我們的角度選擇器,把一切可以變化的介面暴露出來。

最後看一下我們多種多樣的角度選擇器,還是挺好看呀~

希望這篇文章對你有幫助,哪怕只是一些啟發,我也很開心了。

實訓 自定義View

1.自定義view分為自繪控制項和重寫控制項 2.自繪控制項 建立乙個類繼承view,通過重寫ondraw方法,使用canvas,paint等工具完成繪製,然後在activity的布局中引用建立乙個子執行緒,每隔1s重新整理new thread new runnable catch interrup...

Android自定義View 自定義元件

自繪控制項也分兩種,自定義元件和自定義容器,自定義元件是繼承view類,自定義容器時繼承viewgrounp 今天主要分析下自定義元件 還是舉個例子來的實際些,假如我們要畫乙個最簡單的textview,首先想到的就是canvas.drawtext 方法,怎麼畫了?還是得一步一步來 1 寫乙個myte...

Android自定義View實現

android自定義view實現很簡單 繼承view或者其子類,重寫建構函式 ondraw,onmeasure 等函式,根據繼承的類的不同可能有所不同。如果自定義的view需要有自定義的屬性,需要在values下建立attrs.xml。在其中定義你的屬性。在使用到自定義view的xml布局檔案中需要...