【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android自定義View仿騰訊TIM下拉刷新View_第1頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android自定義View仿騰訊TIM下拉刷新View_第2頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android自定義View仿騰訊TIM下拉刷新View_第3頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android自定義View仿騰訊TIM下拉刷新View_第4頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android自定義View仿騰訊TIM下拉刷新View_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android自定義View仿騰訊TIM下拉刷新View

一概述

自定義View是Android開(kāi)發(fā)里面的一個(gè)大學(xué)問(wèn)。偶然間看到TIM郵箱界面的刷新View還挺好玩的,于是就自己動(dòng)手實(shí)現(xiàn)了一個(gè),先看看TIM里邊的效果圖:二需求分析

看到上面的動(dòng)圖,大概也知道我們需要實(shí)現(xiàn)的功能:三功能實(shí)現(xiàn)

新建一個(gè)RefreshView類(lèi)繼承自View,然后我們?cè)僭赗efreshView里面新建一個(gè)內(nèi)部實(shí)體類(lèi):Circle

來(lái)看一下Circle類(lèi)的代碼

#Cirlce.java

這是一個(gè)實(shí)體類(lèi),里面提供了x,y,r,color屬性分別代表圓心坐標(biāo)的x值,y值,圓的半徑r跟顏色。

借助此類(lèi)來(lái)存儲(chǔ)小圓球的相關(guān)屬性。

接下來(lái)就是我們平時(shí)自定義View經(jīng)常要重寫(xiě)的三大方法了,先看onMeasure()

#RefreshView.java

為了適配布局文件中的wrap_content參數(shù),我們需要重寫(xiě)此方法(此方法不是本文的研究重點(diǎn),不明白的可以百度或者google一下,或者參考《Android開(kāi)發(fā)藝術(shù)探索》里面的相關(guān)章節(jié))。

接著看onLayout()方法:

#RefreshView.java

在此方法中調(diào)用了initContentAttr()方法來(lái)初始化內(nèi)容大小與resetCircles()來(lái)初始化(重置)三個(gè)小球的屬性。分別看下這兩個(gè)方法:

#RefreshView.java

這方法很簡(jiǎn)單,就是進(jìn)行了padding的處理,得出真正的布局大小。如果不處理padding的話(huà)那么用戶(hù)設(shè)置了padding將失效。再看resetCircles():

#RefreshView.java

此方法用于初始化和重置小球,方法里面進(jìn)行的兩個(gè)大的if...else語(yǔ)句判斷,第一個(gè)if用于判斷是否應(yīng)該初始化小球,第二個(gè)語(yǔ)句則是用于判斷小球的初始化時(shí)候的形態(tài)??梢栽谕獠空{(diào)用setOriginState()方法來(lái)指定小球的初始化形態(tài),如不指定,則默認(rèn)為NOMAL,即三球重合。

#RefreshView.java

最后就是最有趣的方法onDraw()了:

#RefreshView.java

這方法很簡(jiǎn)單,就是將mCircles列表里面的圓畫(huà)出來(lái)而已(里面進(jìn)行了padding的處理)。

三大方法都講完了,可是這只是畫(huà)出了幾個(gè)小圓球而已,我們需求分析里的需求還沒(méi)實(shí)現(xiàn)呢,上面的方法已經(jīng)把View的基礎(chǔ)搭起來(lái)了,要實(shí)現(xiàn)這個(gè)也就不難了。接下來(lái)就是大家期待的需求實(shí)現(xiàn)了:根據(jù)拖動(dòng)的進(jìn)度來(lái)移動(dòng)小球的位置

實(shí)現(xiàn)代碼如下:

#RefreshView.java

在方法里面進(jìn)行三次判斷,如果初始狀態(tài)是STATE_PREPARED(三小球距離最大,沒(méi)必要再變動(dòng)了)、動(dòng)畫(huà)正在進(jìn)行或者進(jìn)度大于1都不進(jìn)行移動(dòng)。然后修改小球的屬性,再重繪。小球移動(dòng)過(guò)程的動(dòng)畫(huà)

這個(gè)是這個(gè)自定義View最難的部分了,需要一些數(shù)學(xué)的小運(yùn)算,有點(diǎn)繁瑣。

我們先來(lái)理清實(shí)現(xiàn)動(dòng)畫(huà)的邏輯,看了開(kāi)篇的gif,應(yīng)該可以了解到,剛準(zhǔn)備開(kāi)始動(dòng)畫(huà)時(shí),左邊的小球應(yīng)該是處于最左端,中間的小球處于中間,右邊的處于最右端。我們一個(gè)個(gè)小球來(lái)分析。理清小球的移動(dòng)過(guò)程對(duì)代碼的實(shí)現(xiàn)很有幫助,我們可以分析出:

1)每個(gè)小球?qū)τ谧鴺?biāo)系的移動(dòng)特點(diǎn)是一樣的。

2)每個(gè)小球?qū)τ趧?dòng)畫(huà)的進(jìn)度的移動(dòng)特點(diǎn)是不一樣的。

聽(tīng)起來(lái)好像有點(diǎn)拗口,我們用人話(huà)來(lái)解釋一下:

1)每個(gè)小球?qū)τ谧鴺?biāo)系的移動(dòng)特點(diǎn)是一樣的:左邊的小球在坐標(biāo)的最左邊是先出現(xiàn),然后再向右移動(dòng),那么中間和右邊的小球呢?其實(shí)是同樣的,它們?cè)谧鴺?biāo)軸最左邊的時(shí)候都是先出現(xiàn),再向右移動(dòng),無(wú)論哪個(gè)小球,它們?cè)谧鴺?biāo)軸的同一點(diǎn)上的動(dòng)作和形態(tài)應(yīng)該是一致的。

2)每個(gè)小球?qū)τ趧?dòng)畫(huà)的進(jìn)度的移動(dòng)特點(diǎn)是不一樣的:左邊的小球在動(dòng)畫(huà)剛開(kāi)始時(shí)是處于最左端,而中間的小球卻在中間位置,右邊的則在最右端。當(dāng)動(dòng)畫(huà)開(kāi)始后,比如進(jìn)行了一半,這時(shí)候左邊的小球應(yīng)該移動(dòng)到了中點(diǎn)附近,而中間的確是在末端(消失),右邊的小球就會(huì)出現(xiàn)在中間附近。

按照上面分析的邏輯,我把動(dòng)畫(huà)的總進(jìn)度分為6份,為什么是6份呢?通過(guò)上面的動(dòng)畫(huà)分析,知道小球應(yīng)該經(jīng)歷一下過(guò)程(不分時(shí)間先后):為了讓小球之間的間隔保持一個(gè)優(yōu)美的狀態(tài)(動(dòng)畫(huà)開(kāi)始后小球間不會(huì)重疊,相鄰小球的間隔基本一致),就把1、4出現(xiàn)和消失階段分別設(shè)為1/6的動(dòng)畫(huà)周期,中間2、3兩個(gè)階段分別占用1/3個(gè)動(dòng)畫(huà)周期。這樣一來(lái),出現(xiàn)跟消失占用了1/3動(dòng)畫(huà)進(jìn)度,其他兩個(gè)部分分別占用了1/3動(dòng)畫(huà)進(jìn)度。舉個(gè)例子:剛開(kāi)始動(dòng)畫(huà)時(shí),設(shè)最左邊的小球?yàn)?,中間的小球?yàn)?,最右端的小球?yàn)?。

當(dāng)小球1移動(dòng)到中點(diǎn)時(shí),這時(shí)動(dòng)畫(huà)進(jìn)行了1/3,那么此時(shí)的小球2就應(yīng)該移動(dòng)到末端,小球3則剛好經(jīng)歷消失和出現(xiàn)過(guò)程,于是應(yīng)該出現(xiàn)于坐標(biāo)軸的起點(diǎn)。

由此可以看到又恢復(fù)到了剛開(kāi)始時(shí)候的情況(一個(gè)小球在最左,一個(gè)在中,一個(gè)在最右),只不過(guò)是顏色不同了而已。以此類(lèi)推,無(wú)限循環(huán),就可以形成優(yōu)美的動(dòng)畫(huà)了。

分析出這些有什么用呢?我發(fā)現(xiàn)用坐標(biāo)來(lái)確定小球的移動(dòng)實(shí)現(xiàn)起來(lái)會(huì)有點(diǎn)小問(wèn)題,所以就用動(dòng)畫(huà)的進(jìn)度來(lái)實(shí)現(xiàn),下面看具體實(shí)現(xiàn)。

需要實(shí)現(xiàn)小球的無(wú)限運(yùn)動(dòng),最實(shí)用的就是用動(dòng)畫(huà)來(lái)實(shí)現(xiàn),這里我用了屬性動(dòng)畫(huà)。先初始化Animotor類(lèi):

#RefreshView.java

可以看到,這是一個(gè)無(wú)限循環(huán)的動(dòng)畫(huà),如果不手動(dòng)停止,它就會(huì)一直循環(huán)下去。對(duì)于mAnimator,還添加了一個(gè)監(jiān)聽(tīng)器,當(dāng)開(kāi)始動(dòng)畫(huà)是就調(diào)用prepareToStart()方法,這個(gè)方法看起來(lái)是不是有點(diǎn)眼熟,沒(méi)錯(cuò),它就是我們上面resetCircles()里面判斷小球形態(tài)為STATE_PREPARED是調(diào)用過(guò),此方法將確保小球達(dá)到刷新的臨界點(diǎn)。我們主要看看UpdateLisener中的onAnimationUpdate()方法里面的updateCircle()方法:

#RefreshView

我用了一個(gè)virtualFraction來(lái)表示每個(gè)小球的虛擬進(jìn)度(相當(dāng)于上面坐標(biāo)圖中的下值,即坐標(biāo)百分比),例如當(dāng)動(dòng)畫(huà)的總進(jìn)度為0時(shí),左小球的虛擬進(jìn)度就應(yīng)該是1/6+0(默認(rèn)已經(jīng)經(jīng)過(guò)了出現(xiàn)過(guò)程,消耗了1/6),中間小球的虛擬進(jìn)度為1/6+1/3+0=1/2(默認(rèn)經(jīng)歷了出現(xiàn),移動(dòng)到中間過(guò)程),最右邊小球的虛擬進(jìn)度為1/6+1/3+1/3+0=5/6。然后動(dòng)畫(huà)的總進(jìn)度到1/3時(shí),左小球的虛擬進(jìn)度就為1/2(中間位置)

下面再看下move()、appear()、disapear()方法:

#RefreshView

這個(gè)三個(gè)方法都很簡(jiǎn)單,根據(jù)坐標(biāo)的占比來(lái)計(jì)算出小球的坐標(biāo)跟大小。

以上就是整個(gè)RefershView的實(shí)現(xiàn)了,如果需要看源碼的可以拉到文末。四使用及效果

看下怎么使用:

#MainActi

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論