Android?Drawable代碼編寫(xiě)的新姿勢(shì)分享
概念
Drawable表示一種可以在Canvas上進(jìn)行繪制的抽象的概念,它有很多種,常見(jiàn)的如顏色和圖片都可以是一個(gè)Drawable。
優(yōu)點(diǎn)
- 首先,它的使用比較簡(jiǎn)單,在xml里已經(jīng)定義了大量的屬性方法,我們只要熟悉各個(gè)屬性的ui效果和特點(diǎn)就可以自己組合各種的界面效果。
- 其次,它的實(shí)現(xiàn)成本比自定義View低,一些比較簡(jiǎn)單的、定制性、重復(fù)性的UI效果使用drawable將會(huì)縮小開(kāi)發(fā)成本。但是一些比較復(fù)雜的ui場(chǎng)景,drawable卻表現(xiàn)不出自定義view的那種效果。
- 相比較于圖片而言,drawable占用空間更小,這樣有利于縮小apk的體積。
表現(xiàn)形式
Drawable盡管對(duì)于應(yīng)用程序通常不可見(jiàn),但Drawable可以采用多種形式:
Bitmap:最簡(jiǎn)單的Drawable,一個(gè)PNG或JPEG圖像。
Nine Patch:是對(duì)PNG格式的擴(kuò)展允許它指定如何對(duì)其進(jìn)行拉伸和放置的信息
Vector:向量:在XML文件中定義的可繪制的一組點(diǎn),線(xiàn)和曲線(xiàn)以及相關(guān)的顏色信息。 這種類(lèi)型的繪圖可以縮放而不會(huì)損失顯示質(zhì)量。
Shape:形狀:包含簡(jiǎn)單的繪圖命令而不是原始位圖,允許在某些情況下調(diào)整更好。
Layers:圖層:一個(gè)可繪制的復(fù)合物,它在彼此頂部繪制多個(gè)底層可繪圖。
States:狀態(tài),一個(gè)復(fù)合drawable,根據(jù)其狀態(tài)選擇一組drawable中的一個(gè)。
Levels:級(jí)別:一個(gè)復(fù)合drawable,根據(jù)其級(jí)別從一組drawable中選擇一個(gè)。
Scale:比例尺:一個(gè)可繪制的單個(gè)子組合可繪制的組合,其整體大小根據(jù)當(dāng)前級(jí)別進(jìn)行修改。
直接子類(lèi)與非直接子類(lèi)
xml解析流程
最終的inflateFromTag方法
@NonNull @SuppressWarnings("deprecation") private Drawable inflateFromTag(@NonNull String name) { switch (name) { case "selector": return new StateListDrawable(); case "animated-selector": return new AnimatedStateListDrawable(); case "level-list": return new LevelListDrawable(); case "layer-list": return new LayerDrawable(); case "transition": return new TransitionDrawable(); case "ripple": return new RippleDrawable(); case "adaptive-icon": return new AdaptiveIconDrawable(); case "color": return new ColorDrawable(); case "shape": return new GradientDrawable(); case "vector": return new VectorDrawable(); case "animated-vector": return new AnimatedVectorDrawable(); case "scale": return new ScaleDrawable(); case "clip": return new ClipDrawable(); case "rotate": return new RotateDrawable(); case "animated-rotate": return new AnimatedRotateDrawable(); case "animation-list": return new AnimationDrawable(); case "inset": return new InsetDrawable(); case "bitmap": return new BitmapDrawable(); case "nine-patch": return new NinePatchDrawable(); case "animated-image": return new AnimatedImageDrawable(); default: return null; } }
真實(shí)案例
shape | count | radio |
---|---|---|
shape | 833 | 73% |
selector | 240 | 21% |
layer-list | 50 | |
animated-rotate | 7 | |
animation-list | 5 | |
vector | 3 | |
rotate | 2 | |
level-list | 1 |
我的項(xiàng)目里面,統(tǒng)計(jì)了drawable文件的總數(shù)是1140, 其中最多的是shape,總數(shù)833,占比73%, 其次是selector,總數(shù)240,占比21%, 這兩個(gè)加起來(lái)占比達(dá)到94%. 而這兩種類(lèi)型都是差別很小的,主要是背景顏色和圓角角度不同,導(dǎo)致了大量的文件的產(chǎn)生, 而且對(duì)于這類(lèi)的文件命名也是很難統(tǒng)一,從而難以達(dá)到復(fù)用的效果,有時(shí)候找一個(gè)目標(biāo)文件, 遠(yuǎn)遠(yuǎn)沒(méi)有自己創(chuàng)建一個(gè)新的Drawable文件快,所以漸漸的會(huì)導(dǎo)致此類(lèi)文件的爆炸式增長(zhǎng)。 從而增大apk的體積。
通過(guò)xml解析流程,我們可以發(fā)現(xiàn)其中的奧妙,xml也只是根據(jù)具體的標(biāo)簽直接new出來(lái)對(duì)應(yīng)的是類(lèi),然后再直接設(shè)置具體的參數(shù), 如此一來(lái),我們完全可以做到,自己創(chuàng)建具體的對(duì)象,然后設(shè)置參數(shù),這樣就避免了xml解析這一步,
更好的實(shí)現(xiàn)方式 —代碼
mViewBinding.lineDrawable.background = shapeDrawable(this) { lineShape() dash(10, 5) strokeColor(Color.RED) strokeWidth(2) } mViewBinding.stateListDrawable.background = selectorDrawable { pressedDrawable { shapeDrawable(this@MainActivity) { solidColor(Color.BLUE) radius(8) } } defaultDrawable { shapeDrawable(this@MainActivity) { solidColor(Color.GRAY) radius(8) } } }
建議
具體的項(xiàng)目可以在封裝一次,減少每次的創(chuàng)建條件設(shè)置,這樣只需要傳遞具體的參數(shù)就可以,便于復(fù)用, 當(dāng)然,項(xiàng)目也封裝了幾個(gè)通用的方法。比如:
fun shapeDrawableColorInt(context: Context, @ColorInt colorInt: Int = Color.WHITE, radius: Int = 0) = shapeDrawable(context) { solidColor(colorInt) radius(radius) } fun shapeDrawableColorRes(context: Context, @ColorRes colorRes: Int, radius: Int = 0) = shapeDrawable(context) { solidColorRes(colorRes) radius(radius) }
優(yōu)點(diǎn)
比起xml方式可以提升性能:
- 避免xml解析流程
- 復(fù)用這些代碼
- 比xml管理方便
引用方式
implementation 'io.github.weiggle:drawable:1.0.1'
總結(jié)
到此這篇關(guān)于Android Drawable代碼編寫(xiě)的新姿勢(shì)的文章就介紹到這了,更多相關(guān)Android Drawable代碼編寫(xiě)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android NDK中socket的用法以及注意事項(xiàng)分析
本篇文章是對(duì)Android NDK中socket的用法以及注意事項(xiàng)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android通過(guò)自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
通過(guò)自定義ImageView控件,在xml布局里面調(diào)用自定的組件實(shí)現(xiàn)圖片的縮放。下面給大家分享實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2016-10-10Android開(kāi)發(fā)EditText禁止輸入監(jiān)聽(tīng)及InputFilter字符過(guò)濾
這篇文章主要為大家介紹了Android開(kāi)發(fā)EditText禁止輸入監(jiān)聽(tīng)及InputFilter字符過(guò)濾示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Android啟動(dòng)頁(yè)面定時(shí)跳轉(zhuǎn)的三種方法
這篇文章主要介紹了Android啟動(dòng)頁(yè)面定時(shí)跳轉(zhuǎn)的三種方法,實(shí)現(xiàn)打開(kāi)一個(gè)Android手機(jī)APP的歡迎界面后跳轉(zhuǎn)到指定界面的效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11詳解android使用ItemDecoration 懸浮導(dǎo)航欄效果
本篇文章主要介紹了Android 最流行的吸頂效果的實(shí)現(xiàn)及代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-01-01MVVMLight項(xiàng)目之綁定在表單驗(yàn)證上的應(yīng)用示例分析
這篇文章主要為大家介紹了MVVMLight項(xiàng)目中綁定在表單驗(yàn)證上的應(yīng)用示例及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步除夕快樂(lè),新年快樂(lè)2022-01-01