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-06
Android通過(guò)自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
通過(guò)自定義ImageView控件,在xml布局里面調(diào)用自定的組件實(shí)現(xiàn)圖片的縮放。下面給大家分享實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2016-10-10
Android開(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-06
Android啟動(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-01
MVVMLight項(xiàng)目之綁定在表單驗(yàn)證上的應(yīng)用示例分析
這篇文章主要為大家介紹了MVVMLight項(xiàng)目中綁定在表單驗(yàn)證上的應(yīng)用示例及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步除夕快樂(lè),新年快樂(lè)2022-01-01

