Android?Drawable代碼編寫的新姿勢分享
概念
Drawable表示一種可以在Canvas上進行繪制的抽象的概念,它有很多種,常見的如顏色和圖片都可以是一個Drawable。
優(yōu)點
- 首先,它的使用比較簡單,在xml里已經(jīng)定義了大量的屬性方法,我們只要熟悉各個屬性的ui效果和特點就可以自己組合各種的界面效果。
- 其次,它的實現(xiàn)成本比自定義View低,一些比較簡單的、定制性、重復(fù)性的UI效果使用drawable將會縮小開發(fā)成本。但是一些比較復(fù)雜的ui場景,drawable卻表現(xiàn)不出自定義view的那種效果。
- 相比較于圖片而言,drawable占用空間更小,這樣有利于縮小apk的體積。
表現(xiàn)形式
Drawable盡管對于應(yīng)用程序通常不可見,但Drawable可以采用多種形式:
Bitmap:最簡單的Drawable,一個PNG或JPEG圖像。
Nine Patch:是對PNG格式的擴展允許它指定如何對其進行拉伸和放置的信息
Vector:向量:在XML文件中定義的可繪制的一組點,線和曲線以及相關(guān)的顏色信息。 這種類型的繪圖可以縮放而不會損失顯示質(zhì)量。
Shape:形狀:包含簡單的繪圖命令而不是原始位圖,允許在某些情況下調(diào)整更好。
Layers:圖層:一個可繪制的復(fù)合物,它在彼此頂部繪制多個底層可繪圖。
States:狀態(tài),一個復(fù)合drawable,根據(jù)其狀態(tài)選擇一組drawable中的一個。
Levels:級別:一個復(fù)合drawable,根據(jù)其級別從一組drawable中選擇一個。
Scale:比例尺:一個可繪制的單個子組合可繪制的組合,其整體大小根據(jù)當前級別進行修改。
直接子類與非直接子類

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;
}
}真實案例
| 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 |
我的項目里面,統(tǒng)計了drawable文件的總數(shù)是1140, 其中最多的是shape,總數(shù)833,占比73%, 其次是selector,總數(shù)240,占比21%, 這兩個加起來占比達到94%. 而這兩種類型都是差別很小的,主要是背景顏色和圓角角度不同,導(dǎo)致了大量的文件的產(chǎn)生, 而且對于這類的文件命名也是很難統(tǒng)一,從而難以達到復(fù)用的效果,有時候找一個目標文件, 遠遠沒有自己創(chuàng)建一個新的Drawable文件快,所以漸漸的會導(dǎo)致此類文件的爆炸式增長。 從而增大apk的體積。
通過xml解析流程,我們可以發(fā)現(xiàn)其中的奧妙,xml也只是根據(jù)具體的標簽直接new出來對應(yīng)的是類,然后再直接設(shè)置具體的參數(shù), 如此一來,我們完全可以做到,自己創(chuàng)建具體的對象,然后設(shè)置參數(shù),這樣就避免了xml解析這一步,
更好的實現(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)
}
}
}建議
具體的項目可以在封裝一次,減少每次的創(chuàng)建條件設(shè)置,這樣只需要傳遞具體的參數(shù)就可以,便于復(fù)用, 當然,項目也封裝了幾個通用的方法。比如:
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)點
比起xml方式可以提升性能:
- 避免xml解析流程
- 復(fù)用這些代碼
- 比xml管理方便
引用方式
implementation 'io.github.weiggle:drawable:1.0.1'
總結(jié)
到此這篇關(guān)于Android Drawable代碼編寫的新姿勢的文章就介紹到這了,更多相關(guān)Android Drawable代碼編寫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android通過自定義ImageView控件實現(xiàn)圖片的縮放和拖動的實現(xiàn)代碼
通過自定義ImageView控件,在xml布局里面調(diào)用自定的組件實現(xiàn)圖片的縮放。下面給大家分享實現(xiàn)代碼,感興趣的朋友一起看看吧2016-10-10
Android開發(fā)EditText禁止輸入監(jiān)聽及InputFilter字符過濾
這篇文章主要為大家介紹了Android開發(fā)EditText禁止輸入監(jiān)聽及InputFilter字符過濾示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
詳解android使用ItemDecoration 懸浮導(dǎo)航欄效果
本篇文章主要介紹了Android 最流行的吸頂效果的實現(xiàn)及代碼,非常具有實用價值,需要的朋友可以參考下。2017-01-01
MVVMLight項目之綁定在表單驗證上的應(yīng)用示例分析
這篇文章主要為大家介紹了MVVMLight項目中綁定在表單驗證上的應(yīng)用示例及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步除夕快樂,新年快樂2022-01-01

