走進(jìn)源碼,手把手帶你看如何將Android ScrollBar變色

時(shí)下熱門(mén)的換膚框架,不管是Android-skin-support還是Android-Skin-Loader,亦或者是其它名為插件化、

無(wú)感知的換膚框架,無(wú)論說(shuō)的有多么天花亂墜,其本質(zhì)還是設(shè)置控件的background、src或者是textColor,實(shí)際上就是換背景(前景)圖片或者背景/文字顏色。

這些基本都滿(mǎn)足公司的業(yè)務(wù)需求

直到有一天我看到UI給的效果圖上一個(gè)listview的滾動(dòng)條也需要變顏色,what?這么細(xì)致的設(shè)計(jì)也是要點(diǎn)贊了。

看到這個(gè)需求后,第一反應(yīng)是滾動(dòng)條不屬于listview的背景,所以沒(méi)法用常規(guī)方法設(shè)置。

只能換種思路,因?yàn)槠つw框架有api可以直接獲取到皮膚包里的色值,所以可以拿到這個(gè)色值設(shè)置到滾動(dòng)條中。

那么問(wèn)題就落在如何拿到滾動(dòng)條并且設(shè)置它的背景色了。

首先,看下listView有沒(méi)有直接拿到滾動(dòng)條的方法。

很可惜,并沒(méi)有直接getScrollBar()的方法,set也沒(méi)有能直接設(shè)置scrollBar的背景方法:

看來(lái)可能谷歌覺(jué)得滾動(dòng)條沒(méi)必要訂制化,就沒(méi)有對(duì)外暴露api了,我們只能找到滾動(dòng)條在具體哪個(gè)類(lèi)里哪個(gè)屬性再通過(guò)反射拿到它。

既然都要設(shè)置size了,肯定要先拿到scrollBar本身才行吧,點(diǎn)進(jìn)去看到是一個(gè)get方法

繼續(xù)點(diǎn)進(jìn)去,OK,看到一個(gè)叫做mScrollCache的成員變量,其類(lèi)型是ScrollabilityCache

再點(diǎn)進(jìn)這個(gè)類(lèi),看看里面有什么。

ScrollabilityCache這個(gè)類(lèi)是View里面的一個(gè)靜態(tài)內(nèi)部類(lèi),可以看到它有個(gè)ScrollBarDrawable類(lèi)型的成員變量 scrollBar。這不就是我們要找的東西嘛,看見(jiàn)以Drawable結(jié)尾的后綴,頓時(shí)也放心了很多,基本上判定scrollBar是個(gè)drawable了,改顏色當(dāng)然沒(méi)問(wèn)題了。

(Tips: 這里需要插一句,ScrollabilityCache是View的內(nèi)部類(lèi),所以其實(shí)可以這么說(shuō),所有的view都有scrollBar,并不是ListView或者RecycleView獨(dú)有的,最早先的時(shí)候我以為是listview里獨(dú)有的,于是從listView里開(kāi)始找scrollBar,結(jié)果一路找到View。。。它們之間的繼承關(guān)系如下:ListView?--> AbsListView?--> AdapterView?--> ViewGroup?--> View)

為了證實(shí)scrollBar是個(gè)drawable的設(shè)想,我們繼續(xù)向下看,但是這里ScrollBarDrawable是標(biāo)紅的,Android Studio中沒(méi)法跳轉(zhuǎn),我們只有借助看源碼神器 source Insight了(具體方法自行百度,反正很簡(jiǎn)單)。在source Insight找到這個(gè)類(lèi)后,我們發(fā)現(xiàn)ScrollBarDrawable確實(shí)是繼承Drawable的。

查看注釋1,發(fā)現(xiàn)這個(gè)類(lèi)添加了hide注解,說(shuō)明這個(gè)類(lèi)是隱藏的,沒(méi)法通過(guò)API調(diào)用。只能通過(guò)反射調(diào)用了。

查看注釋2,發(fā)現(xiàn)主要是這四個(gè)成員變量,橫豎各兩個(gè),Track是滾動(dòng)條的那個(gè)滑塊,Thumb是滾動(dòng)條的背景,我們通過(guò)反射拿到這幾個(gè)成員變量再通過(guò)對(duì)應(yīng)的setXXX方法去設(shè)置即可。

具體的實(shí)現(xiàn)代碼如下(以垂直滾動(dòng)條為例):

因?yàn)楹?jiǎn)書(shū)沒(méi)有代碼排版,所以只能截圖了

雖然我們文章切入點(diǎn)是關(guān)于換膚的,但是這些方法也很適合scrollBar的UI定制化。到這里,滾動(dòng)條的故事基本就到此結(jié)束了。

不過(guò)我覺(jué)得可以再延展一下。

在項(xiàng)目中,經(jīng)常會(huì)遇到不同的皮膚只是換個(gè)顏色,比如說(shuō)類(lèi)似下圖的icon

它們顏色單一,內(nèi)容簡(jiǎn)單,不同皮膚的區(qū)別只是顏色不一,這種情況完全就沒(méi)必要做幾套切圖,只需要做一套默認(rèn)的切圖,然后通過(guò)drawable的setTint(Drawable drawable,int color)方法直接變色,方便很多。

你,Get到了嗎?

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

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