之前說想要寫一篇自動補全的EditText,不過后來隨便寫了一下,發(fā)現(xiàn)并沒有想象中的簡單,加上最近項目進度一直在趕,沒時間認認真真搗鼓了,看到騰訊的手機管家加速球還不錯,而且實現(xiàn)起來邏輯不是很復雜,所以這周就嘗試如何實現(xiàn)加速球這種動畫效果。
先來看看手機管家的加速球是什么樣的


功能需求
這個控件大概需要實現(xiàn)三個部分的功能
1、在最底層畫出一個圓
2、畫出底層的小波浪和外層的大波浪(一開始我以為這兩個波浪是分開的,后來發(fā)現(xiàn)合在一起更加好實現(xiàn))
3.添加橫向的動畫,設置一個修改水位的縱向動畫
4、我發(fā)現(xiàn)手機管家在水位下降之后沒有根據(jù)當前的手機內存耗用情況把刷新水位,雖然我不是很理解,不過我認為應該加上的,添加一個回調。
知識點,也是難點
首先肯定是先定義一個BallView繼承自View類了,接著重寫onDraw方法。那么在重寫onDraw方法之前,先介紹一下今天涉及到canvas的一些知識,但是都不會擴展來講,因為要學好自定義控件,以下的東西都必須要掌握的:
貝塞爾曲線:關于貝塞爾曲線,我想學習過自定義控件的人都會接觸到,因為它對于繪制曲線非常的強大,而我們大多數(shù)情景下繪制的東西都不是標準的圓或者矩形。
setXfermode():這是Paint里面的一個API,設置圖片相交模式,對于多圖層疊的時候,這個函數(shù)就會非常的強大,雖然設置起來很簡單,但是要理解記住每一種模式也是相當困難的。
離屏繪制:涉及到Canvas的圖層概念,雖然簡單來說只有兩行代碼。
接下來就是正文部分了,因為這個功能很簡單,而且對于嘗試自定義控件的朋友會覺得蠻有意思的吧,所以我就按著我自己的思路直接從代碼上來講解如何實現(xiàn)這個動畫效果了:
1、我們知道畫筆對象其實就那么幾個,就好比如我們畫畫的時候,首先需要準備好紙畫筆顏料這些零零碎碎的東西,紙就是系統(tǒng)提供給我們的Canvas對象了,而至于畫筆我們需要提前準備好:

不知道大家有沒有用過TakeColor這個取色工具,上面的顏色就是用這個工具取得,以后要是我們獨立開發(fā)的時候看到好的顏色搭配,可以直接用這個工具就知道顏色的RGB值了。
2、接下來就是今天想重點講解的部分了,我們都知道貝塞爾曲線能夠畫出波浪形的圓滑的路徑,但是要怎么滑還是需要斟酌斟酌,像手機管家中的加速球的波浪是有內外兩層的,這樣給人一種立體感,用戶體驗也就蹭蹭上去了。畢竟,用戶體驗就是用戶使用過程中的感覺嗎,細節(jié)很重要啊。接下來就看看這個自定義控件是如何進行繪圖的吧:
onDraw:

在這里可以看到一共調用了canvas的兩次draw方法,所畫即所得:
畫圓:

必須加一個背景,不然圖層混合后,兩個圖層重合部分的透明區(qū)域都會消失,重疊之后就看不到波浪的圓背景了。如下圖所示:

畫內層小波浪:

? ? ?小波浪的路徑其實是有講究的,要是小波浪跟大波浪的路徑方向是一樣的,即從左到右,你就會發(fā)現(xiàn)壓根看不出波浪流動的效果了,因為大小波浪都往同一個方向勻速地運動,那么他們相對是靜止的。這個時候我想有兩個方法,第一個方法是設置兩個速率不一樣的屬性動畫,那么我們就可以看到這兩個動畫相對是
運動
的。不過這里我用的是第二個方法,用的是同一個屬性動畫,但是大波浪是從左到右,而小波浪是從右到左的。這樣不管速率問題,他們相互都是
運動
的。最后稍微添加一點水平方向的偏移量,設置rQuad的第一個參數(shù),也就是轉點的坐標均小于大波浪的轉點坐標,就可以實現(xiàn)前浪(大波浪)比后浪(小波浪)更大的效果。PS:水平偏移量跟波浪的波峰我想是有關聯(lián)的,不過具體如何這里就無從考究了。
這里再說一下具體的路徑是怎么考慮的。我們繪制組件的時候,最困擾我們的可能是Path路徑的創(chuàng)建,有了路徑,剩下的就只是上色還有兩個圖層重疊時如何顯示了。
mWaveLength:一個波浪(有起有伏)的長度,如果波浪長度少于控件的寬度,那么控件就會顯示多個波浪,在這里這個值設置為控件的實際寬度,而轉點的x坐標決定波峰在波浪中的水平位置。
d_value:動畫在水平方向上的偏移量,因為這個偏移量是波浪的一個周期,所以for循環(huán)的起點是-mWaveLength+getX(),這樣不管d_value怎么改變,波浪不會"斷"掉,那么終點為什么設置為getWidth+mWaveLength呢,這里純粹是邏輯上視圖更加連貫而已。
畫外層大波浪:

這里大致上和獲取小波浪是一樣的,不一樣的地方是,起始點moveTo的坐標,大波浪的起點是從左到右的,水位線startPosition就是我們設定的值。
該畫的部分都已經(jīng)畫完了,接下來就是動畫部分了。動畫部分難度不大,動畫的速度就是波浪流動的速度,所以duration不要設置的太小??傮w來說都不復雜,只是要實現(xiàn)流動很自然的效果,就要用點心了。直接貼代碼了
水平方向的動畫(波浪流動)

豎直方向的動畫(設置水位,水位上升下降的動畫)

整個控件制作過程就是這樣了,難度要比EditText簡單很多很多,當然跟那些很炫很炫的控件是沒法比的,尤其是跟數(shù)據(jù)綁定在一起的控件,至于手機管家上的那個小飛機,pressed的時候飛機放大,點擊的時候飛機上升,水位下降,然后飛機再從底下升起來,這些實現(xiàn)起來都不難,但是這些效果這里不擴展了。
所以最終實現(xiàn)出來的效果是

以后有空再寫一篇圖層混合模式還有View事件的分發(fā)消費攔截,感覺像我這樣的新手學習這兩個東西的時候總是不得要領!得先把狠話擱下了督促一下自己才行-_-||,媽的最近壓力好大,債臺高筑啊