下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(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ù)】教你五分鐘實(shí)現(xiàn)Android超漂亮的刻度輪播控件實(shí)例教程
前言最近一直在做音視頻的工作,已經(jīng)有大半年沒(méi)有寫應(yīng)用層的東西了,生怕越來(lái)越生疏。正好前段時(shí)間接了個(gè)外包項(xiàng)目,才得以回顧一下。項(xiàng)目中有一個(gè)控件挺簡(jiǎn)潔漂亮的,而且用到的技術(shù)也比較基礎(chǔ),比較適合新手學(xué)習(xí),所以單獨(dú)開(kāi)源出來(lái),希望能對(duì)初學(xué)者有所幫助。
截圖
截屏
一、自定義View的常用方法
相信每個(gè)Android程序員都知道,我們每天的開(kāi)發(fā)工作當(dāng)中都在不停地跟View打交道,Android中的任何一個(gè)布局、任何一個(gè)控件其實(shí)都是直接或間接繼承自View的,如TextView、Button、ImageView、ListView等。一些接觸Android不久的朋友對(duì)自定義View都有一絲畏懼感,總感覺(jué)這是一個(gè)比較高級(jí)的技術(shù),但其實(shí)自定義View并不復(fù)雜,有時(shí)候只需要簡(jiǎn)單幾行代碼就可以完成了。說(shuō)到自定義View,總繞不開(kāi)下面幾個(gè)方法1.overridefunonMeasure(widthMeasureSpec:Int,heightMeasureSpec:Int)
??初始化View時(shí),用于測(cè)量大小,并對(duì)View的大小進(jìn)行控制,比如可以控制View的寬高比例。2.overridefunonDraw(canvas:Canvas)
??View的繪制回調(diào),所有的畫筆、畫布操作都在這里。切勿在此方法進(jìn)行耗時(shí)操作,能在外部計(jì)算的都在外部計(jì)算,并且盡量不要在這里初始化變量。因?yàn)檎G闆r下這個(gè)方法會(huì)以60fps的速度進(jìn)行回調(diào),如果有耗時(shí)操作,將會(huì)卡頓,如果初始化大量對(duì)象,則會(huì)消耗大量?jī)?nèi)存??傊?,跟畫布無(wú)關(guān)的操作都不要寫在這里。3.invalidate()
??用于通知View進(jìn)行重繪,也就是重新調(diào)用onDraw,當(dāng)我們界面屬性發(fā)生變化時(shí),就可以調(diào)用該方法來(lái)進(jìn)行重繪,而不是調(diào)用onDraw,這個(gè)方法非常常用。4.overridefunonTouchEvent(event:MotionEvent):Boolean
??相信大家都知道,這個(gè)是觸摸事件回調(diào)。在這里可以處理一些手勢(shì)操作。二、自定義一個(gè)刻度控件RulerView
??由于代碼比較多,而且源碼里面的注釋也比較詳細(xì),所以這里只挑重點(diǎn)的幾個(gè)方法講解一下。如果有問(wèn)題,或者錯(cuò)誤,歡迎在評(píng)論區(qū)留言。
??觀察本文開(kāi)始的視頻,我們可以發(fā)現(xiàn),該控件雖然看起來(lái)挺簡(jiǎn)潔,但是需要控制的部分卻不少,光刻度就有三種類型,還有一些文字。
普通刻度,寬度比較短,顏色比較淺,不帶文字。
整10刻度,寬度比較長(zhǎng),顏色相較普通刻度深一點(diǎn),并且?guī)в形淖帧?/p>
游標(biāo)刻度,寬度在三類刻度里面是最長(zhǎng)的,顏色高亮,并且也帶有文字。
標(biāo)簽文字,用于描述該刻度的用途。
普通刻度,寬度比較短,顏色比較淺,不帶文字。
整10刻度,寬度比較長(zhǎng),顏色相較普通刻度深一點(diǎn),并且?guī)в形淖帧?/p>
游標(biāo)刻度,寬度在三類刻度里面是最長(zhǎng)的,顏色高亮,并且也帶有文字。
標(biāo)簽文字,用于描述該刻度的用途。
??以上都是需要我們用畫筆來(lái)繪制的,所以我們定義了以下幾個(gè)畫筆,為了避免在onDraw中頻繁更改畫筆屬性,這里又對(duì)文字和刻度定義了單獨(dú)的畫筆,目的是避免任何畫筆屬性的改變和在onDraw中改變屬性導(dǎo)致繪制過(guò)于耗時(shí),更重要的是來(lái)回更改畫筆的屬性過(guò)于復(fù)雜,不便于操作和問(wèn)題排查。
scalePaint:Paint//刻度畫筆
scalePointerPaint:Paint//整10刻度文字畫筆
scalePointerTextPaint:Paint//整10刻度文字畫筆
cursorPaint:Paint//游標(biāo)畫筆
cursorTextPaint:Paint//游標(biāo)文字畫筆
cursorLabelPaint:Paint//標(biāo)簽文字畫筆
scalePaint:Paint//刻度畫筆
scalePointerPaint:Paint//整10刻度文字畫筆
scalePointerTextPaint:Paint//整10刻度文字畫筆
cursorPaint:Paint//游標(biāo)畫筆
cursorTextPaint:Paint//游標(biāo)文字畫筆
cursorLabelPaint:Paint//標(biāo)簽文字畫筆
1、從xml設(shè)置的屬性初始化參數(shù)
??除了基礎(chǔ)的畫筆對(duì)象,還需要一些畫筆必要的屬性,比如我們繪制一個(gè)刻度,需要知道刻度位置、大小和間距。所以圍繞這些,又定義了一系列屬性。這些屬性可以由xml定義時(shí)提供,由此引出View的另一個(gè)重要用法。
??這個(gè)用法比較固定,都是這個(gè)套路。其中需要注意的是,類似于R.styleable.app_scaleWidth這種id是在values/attrs.xml中定義的,app代表命名空間,可以自定義,scaleWidth就是屬性id,跟layout_width這些是一樣的。我們?cè)谝粋€(gè)命名空間中定義了一個(gè)屬性id后,就可以像使用layout_width和layout_height那樣從xml中向View傳遞屬性了。此時(shí)在View的構(gòu)造方法中可以直接獲取這些屬性值,代碼如下。2、繪制View
??本文并沒(méi)有使用View提供的scrollTo和scrollBy來(lái)控制滾動(dòng),而是重新定義一個(gè)x,y屬性來(lái)記錄滾動(dòng)位置,通過(guò)這個(gè)屬性繪制相應(yīng)的位置,來(lái)實(shí)現(xiàn)滾動(dòng)效果。這樣操作可以通過(guò)指定繪制區(qū)域(屏幕外的內(nèi)容不繪制,感興趣的同學(xué)可以去嘗試實(shí)現(xiàn))來(lái)解決性能問(wèn)題。
??drawScale通過(guò)遍歷items來(lái)繪制每一個(gè)元素,包括刻度和對(duì)應(yīng)的文字,都是比較基本的操作。需要注意的是canvas.drawText默認(rèn)情況下的x,y是指文字的左下角位置。3、支持滾動(dòng)
??Android的手勢(shì)滾動(dòng)操作比較簡(jiǎn)單,不需要自己去實(shí)現(xiàn)各種邏輯控制,而是通過(guò)系統(tǒng)提供的Scroller來(lái)計(jì)算滾動(dòng)位置。
??首先我們需要一個(gè)GestureDetectorCompat和OverScroller,前者用于手勢(shì)監(jiān)聽(tīng),后者通過(guò)MotionEvent來(lái)計(jì)算滾動(dòng)位置。
1.mGestureDetector:GestureDetectorCompat
2.scroller:OverScroller
1.mGestureDetector:GestureDetectorCompat2.scroller:OverScroller
??構(gòu)造一個(gè)GestureDetectorCompat對(duì)象,需要先提供一個(gè)OnGestureListener,用來(lái)監(jiān)聽(tīng)onScroll和onFling事件。其實(shí)就是MotionEvent經(jīng)過(guò)GestureDetectorCompat處理之后,就變成了可以直接使用的滾動(dòng)和慣性滾動(dòng)事件,然后通過(guò)這兩個(gè)回調(diào)通知我們。
??在onScroll中,我們通過(guò)橫向和縱向滾動(dòng)距離來(lái)計(jì)算滾動(dòng)方向,如果橫向滾動(dòng)距離大于縱向滾動(dòng)距離,我們則可以認(rèn)為是橫向滾動(dòng),反之則是縱向滾動(dòng)。本文只需要縱向滾動(dòng)。
??拿到滾動(dòng)方向之后,我們就可以對(duì)滾動(dòng)位置x,y進(jìn)行累加,記錄每一次滑動(dòng)之后的新的位置。最后通過(guò)postInvalidateOnAnimation或invalidate來(lái)通知重新繪制,onDraw根據(jù)新的x,y繪制對(duì)應(yīng)位置的畫面,來(lái)實(shí)現(xiàn)滑動(dòng)。
??雖然通過(guò)onScroll已經(jīng)實(shí)現(xiàn)了View的滑動(dòng),但只是實(shí)現(xiàn)跟隨手指運(yùn)動(dòng),還沒(méi)有實(shí)現(xiàn)“拋”的動(dòng)作。在現(xiàn)實(shí)世界中,運(yùn)動(dòng)是有慣性的,如果只實(shí)現(xiàn)onScroll,一切都顯得很生硬。那么如何實(shí)現(xiàn)慣性運(yùn)動(dòng)呢,我們自己計(jì)算?想想都可怕,這么多運(yùn)動(dòng)函數(shù),相信不是一般人能應(yīng)付的來(lái)的。幸運(yùn)的是,這個(gè)計(jì)算我們可以交給GestureDetectorCompat的onFling。
??onFling有四個(gè)參數(shù),前兩個(gè)是MotionEvent,分別代表前后兩個(gè)觸摸事件。velocityX:Float代表X軸滾動(dòng)速率,velocityY:Float代表Y軸滾動(dòng)速率,我們不需要關(guān)心這兩個(gè)值如何,直接交給scroller處理即可。
??這里也許有人要問(wèn)了,我們的手指離開(kāi)屏幕之后便不再產(chǎn)生事件,View是如何實(shí)現(xiàn)持續(xù)滑動(dòng)的呢。再回頭看一下onFling回調(diào)也確實(shí)如此,onFling只會(huì)根據(jù)手指離開(kāi)屏幕前兩個(gè)MotionEvent來(lái)計(jì)算速率,之后就再也沒(méi)有回調(diào),所以scroller.fling也僅僅是調(diào)用了一次,并不能持續(xù)滾動(dòng)。那我們?nèi)绾螌?shí)現(xiàn)持續(xù)的慣性滾動(dòng)呢?
??要實(shí)現(xiàn)持續(xù)的慣性滾動(dòng),就得依賴于overridefuncomputeScroll(),該方法由draw過(guò)程中調(diào)用,我們可以通過(guò)invalidate->onDraw->computeScroll->invalidate這樣一個(gè)循環(huán)來(lái)控制慣性滾動(dòng),直至慣性滾動(dòng)停止,具體實(shí)現(xiàn)可以參考文章最后的源碼。??至此自定義View的繪制和事件兩個(gè)重要部分都講完了。喜歡的話記得點(diǎn)贊、評(píng)論和關(guān)注,您的關(guān)注是我的鼓勵(lì)。文章最后貼出相關(guān)源碼,歡迎查閱學(xué)習(xí)。如果有問(wèn)題,或者錯(cuò)誤,歡
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東科貿(mào)職業(yè)學(xué)院《英語(yǔ)閱讀4》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東酒店管理職業(yè)技術(shù)學(xué)院《安全人機(jī)工程課程設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東交通職業(yè)技術(shù)學(xué)院《教師職業(yè)道德規(guī)范》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東工商職業(yè)技術(shù)大學(xué)《生物制藥過(guò)程自動(dòng)化技術(shù)》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東第二師范學(xué)院《系統(tǒng)化品牌設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東潮州衛(wèi)生健康職業(yè)學(xué)院《名案研討》2023-2024學(xué)年第一學(xué)期期末試卷
- 《總分析誤差》課件
- 《干部管理技能精座》課件
- 廣安職業(yè)技術(shù)學(xué)院《中醫(yī)眼科學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 共青科技職業(yè)學(xué)院《品牌與形象》2023-2024學(xué)年第一學(xué)期期末試卷
- 人教版5年級(jí)上冊(cè)音樂(lè)測(cè)試(含答案)
- 中國(guó)電信-空地一體5G增強(qiáng)低空網(wǎng)絡(luò)白皮書2024
- 2023-2024學(xué)年江蘇省連云港市贛榆區(qū)九年級(jí)(上)期末英語(yǔ)試卷
- 八年級(jí)上冊(cè)道德與法治期末試卷3(開(kāi)卷)
- 機(jī)械工程學(xué)科研究前沿
- 朝鮮戶籍制度
- 汽車電器DFMEA-空調(diào)冷暖裝置
- 河北省滄州市2023-2024學(xué)年高一上學(xué)期期末考試語(yǔ)文試題(含答案解析)
- 2024屆四川省成都市中考數(shù)學(xué)第一輪復(fù)習(xí)之中考考點(diǎn)研究《一次函數(shù)與反比例函數(shù)綜合問(wèn)題》教學(xué)
- 2023AECOPD診治中國(guó)專家共識(shí)
- 2024-2025年上半學(xué)期(三年級(jí))教科版上冊(cè)科學(xué)平時(shí)訓(xùn)練試卷【可打印】
評(píng)論
0/150
提交評(píng)論