Android中的Drawable
Drawable
表示的是一種可以在Canvas
上進(jìn)行繪制的抽象的概念盲链,它的種類有很多掌猛,最常見的顏色和圖片都可以是一個(gè)Drawable
奈嘿。
Drawable
在開發(fā)中有著自己的優(yōu)點(diǎn):首先,它使用簡(jiǎn)單搬设,比自定義View
的成本要低鞋诗;其次膀捷,非圖片類型的Drawable
占用空間較小,這對(duì)減少apk
的大小也很有幫助削彬。
1. Drawable簡(jiǎn)介
Drawable
有很多種全庸,它們都表示一種圖像的概念,但是它們又不全是圖片吃警,通過顏色也可以構(gòu)造出各式各樣的圖像的效果糕篇。在Android
的設(shè)計(jì)中,Drawable
是一個(gè)抽象類酌心,它是所有Drawable
對(duì)象的基類,每個(gè)具體的Drawable
都是它的子類挑豌,比如ShapeDrawable
安券,BitmapDrawable
等墩崩。
Drawable
的內(nèi)部寬/高這個(gè)參數(shù)比較重要,通過getIntrinsicWidth
和getIntrinsicHeight
這兩個(gè)方法可以獲取到它們侯勉。但是并不是所有的Drawable
都有內(nèi)部寬/高鹦筹,比如一張圖片所形成的的Drawable
,它的內(nèi)部寬/高就是圖片的寬/高址貌,但是一個(gè)顏色所形成的Drawable
铐拐,它就沒有內(nèi)部寬/高的概念。另外需要注意的是练对,Drawable
的內(nèi)部寬/高不等同于它的大小遍蟋,一般來說,Drawable
是沒有大小概念的螟凭,當(dāng)用作View
的背景時(shí)虚青,Drawable
會(huì)被拉伸至View
的同等大小。
2. Drawable的分類
1. BitmapDrawable
這幾乎是最簡(jiǎn)單的Drawable
了螺男,它表示的就是一張圖片棒厘。在實(shí)際開發(fā)中,我們可以直接引用原始的圖片即可下隧,但是也可以通過XML
的方式來描述它奢人,通過XML
來描述的BitmapDrawable
可以設(shè)置更多的效果。
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/mainback"
android:antialias="true"
android:dither="true"
android:filter="true"
android:gravity="center"
android:mipMap="false"
android:tileMode="repeat"/>
android:src
圖片的資源id
android:antialias
是否開啟圖片抗鋸齒功能淆院。開啟后會(huì)讓圖片變得平滑何乎,同時(shí)也會(huì)在一定程度上降低圖片的清晰度,但是這個(gè)降低的幅度較低以至于可以忽略迫筑,因此抗鋸齒選項(xiàng)應(yīng)該開啟宪赶。
android:dither
是否開啟抖動(dòng)效果。當(dāng)圖片的像素配置和手機(jī)屏幕的像素配置不一致時(shí)脯燃,開啟這個(gè)選項(xiàng)可以讓高質(zhì)量的圖片在低質(zhì)量的屏幕上還能保持較好的顯示效果搂妻。在Android
中設(shè)置的Bitmap
一般會(huì)選用ARGB8888
這個(gè)模式,即ARGB
四個(gè)通道各占8位辕棚,在這種色彩模式下欲主,一個(gè)像素所占的大小為4個(gè)字節(jié),一個(gè)像素的位數(shù)總和越高逝嚎,圖像也就越逼真扁瓢。
android:filter
是否開啟過濾效果,當(dāng)圖片尺寸被拉伸或者壓縮時(shí)补君,開啟過濾效果可以保持較好的顯示效果引几,因此此選項(xiàng)也應(yīng)該開啟。
android:gravity
當(dāng)圖片小于屏幕的尺寸時(shí)挽铁,設(shè)置此選項(xiàng)可以對(duì)圖片進(jìn)行定位伟桅。這個(gè)屬性的可選項(xiàng)比較多敞掘,不同的選項(xiàng)可以通過|
來組合使用。
android:mipMap
這是一種圖像相關(guān)的處理技術(shù)楣铁,也叫紋理映射玖雁,比較抽象,默認(rèn)值為false盖腕,在日常開發(fā)中此選項(xiàng)不常用赫冬。
android:tileMode
平鋪模式。這個(gè)選項(xiàng)有如下幾個(gè)值:repeat
溃列,mirror
劲厌,clamp
,disabled
哭廉。其中disabled
表示關(guān)閉平鋪模式脊僚,這也是默認(rèn)值。repeat
表示的是簡(jiǎn)單的水平和豎直方向上的平鋪效果遵绰;mirror
表示一種在水平和豎直方向上的鏡面投影效果辽幌;clamp
表示的效果就更加奇特,圖片四周的像素會(huì)拓展到周圍區(qū)域椿访。
NinePatchDrawable
它表示的是一張.9
格式的圖片乌企,.9
圖片可以自動(dòng)地根據(jù)所需的寬/高進(jìn)行相應(yīng)的縮放,并保證不失真成玫,和BitmapDrawable
一樣加酵,在實(shí)際的使用中直接引用圖片即可,但是也可以通過XML來描述.9
圖哭当。
<?xml version="1.0" encoding="utf-8"?>
<nine-patch
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"
android:dither="true">
</nine-patch>
上述XML
中的屬性的含義和BitmapDrawable
中的對(duì)應(yīng)屬性的含義是相同的猪腕。
2. ShapeDrawable
android:shape
表示圖形的形狀,有四個(gè)選項(xiàng)钦勘,rectangle
(矩形)陋葡,oval
(橢圓),line
(線性)彻采,ring
(圓環(huán))腐缤。它的默認(rèn)值是矩形,另外line
和ring
這兩個(gè)選項(xiàng)必須要通過<stroke>
標(biāo)簽來指定線的寬度和顏色等信息肛响,否則將無法達(dá)到預(yù)期的顯示效果岭粤。
針對(duì)ring
這個(gè)形狀,有5個(gè)特殊的屬性特笋,android:innerRadius
剃浇,android:thickness
,android:innerRadiusRatio
,android:thicknessRatio
偿渡,android:useLevel
臼寄。含義如下表所示:
·corners·
表示shape
的四個(gè)角的角度霸奕,它只適用于矩形shape
溜宽,這里的角度是指圓角的程度。
android:radius
為4個(gè)角同時(shí)設(shè)定相同的角度质帅,優(yōu)先級(jí)較低适揉,會(huì)被其他四個(gè)屬性覆蓋。
android:topLeftRadius
設(shè)定左上角的角度
android:topRightRadius
設(shè)定右上角的角度
android:bottomLeftRadius
設(shè)定左下角的角度
android:bottomRightRadius
設(shè)定右下角的角度
gradient
它與<solid>
標(biāo)簽是互相排斥的煤惩,其中solid
表示純色填充嫉嘀,而gradient
則表示漸變效果。
android:angle
漸變的角度魄揉,默認(rèn)為0
剪侮,其值必須為45
的倍數(shù),0
表示從左到右洛退,90
表示從下到上瓣俯。
android:centerX
漸變的中心點(diǎn)的橫坐標(biāo)
android:centerY
漸變的中心點(diǎn)的縱坐標(biāo),漸變的中心點(diǎn)會(huì)影響漸變的具體效果
android:startColor
漸變的起始色
android:centerColor
漸變的中間色
android:endColor
漸變的結(jié)束色
android:gradientRadius
漸變半徑兵怯,僅當(dāng)android:type="radial"
時(shí)有效
android:useLevel
一般為false
彩匕,當(dāng)Drawable
作為StateListDrawable
使用時(shí)為true
。
android:type
漸變的類型媒区,有linear
(線性漸變)驼仪,radial
(徑向漸變),sweep
(掃描線漸變)三種袜漩,其中默認(rèn)值為線性漸變绪爸。
solid
這個(gè)標(biāo)簽表示純色填充,通過
android:colo
r即可指定shape
中填充的顏色
stroke
shape
的描邊
android:width
描邊的寬度粘优,越大則shape
的邊緣線就會(huì)看起來越粗仇味。
android:color
描邊的顏色
android:dashWidth
組成虛線的線段的寬度
android:dashGap
組成虛線的線段之間的間隔,間隔越大則虛線看起來空隙就越大雹顺。注意:如果android:dashWidth
和android:dashGap
有任何一個(gè)為0丹墨,那么虛線效果將不能生效。
padding
這個(gè)表示空白嬉愧,但是它表示的不是shape
的空白贩挣,而是包含它的View
的空白,有四個(gè)屬性:android:top
,android:right
,android:bottom
,android:left
。
size
設(shè)置的寬/高就是ShapeDrawable
的固有寬高王财,但是作為View
的背景時(shí)卵迂,shape
還會(huì)被拉伸或者縮小為View
的大小。
3. LayerDrawable
LayerDrawable
對(duì)應(yīng)的XML
標(biāo)簽是layer-list
,它表示一種層次化的Drawable
集合绒净,通過將不同的Drawable
放置到不同的層上面從而達(dá)到一種疊加后的效果见咒。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--第一層-->
<item>
<shape android:shape="rectangle">
<solid android:color="#0ac39e"/>
</shape>
</item>
<!--第二層-->
<item android:bottom="6dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
</shape>
</item>
<!--第三層-->
<item android:bottom="1dp"
android:left="1dp"
android:right="1dp">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF"/>
</shape>
</item>
<item android:drawable="@drawable/ic_launcher"
android:gravity="right">
</item>
</layer-list>
一個(gè)layer-list
中可以包含多個(gè)item
,每個(gè)item
表示一個(gè)Drawable
挂疆,item
的結(jié)構(gòu)也比較簡(jiǎn)單改览,比較常用的屬性有android:bottom
,android:left
缤言,android:right
宝当,android:top
,它們分別表示Drawable
相對(duì)于View
的上下左右的偏移量胆萧,單位為px
庆揩。另外,我們可以通過android:drawable
屬性來直接引用一個(gè)已有的Drawable
資源跌穗,也可以在item
中自定義Drawable
订晌。默認(rèn)情況下,layer-list
中的所有Drawable
都會(huì)被縮放至View
的大小瞻离,對(duì)于Bitmap
來說腾仅,需要使用android:gravity
屬性才能控制圖片的顯示效果。layer-list
有層次的概念套利,下面的Item會(huì)覆蓋上面的item推励,通過合理的分層,可以實(shí)現(xiàn)一些特殊的疊加效果肉迫。
4. StateListDrawable
StateListDrawable
對(duì)應(yīng)于<selector>
標(biāo)簽,它也是表示Drawable
集合验辞,每個(gè)Drawable
都對(duì)應(yīng)著View
的一種狀態(tài),這樣系統(tǒng)就會(huì)根據(jù)View
的狀態(tài)來選擇合適的Drawable
喊衫。
<selector
xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="false"
android:dither="true"
android:variablePadding="false">
<item
android:drawable="@drawable/shape_main"
android:state_pressed="true"/>
<item
android:drawable="@color/colorAccent"/>
</selector>
android:constantSize
StateListDrawable
的固有大小是否隨著其狀態(tài)的改變而改變跌造,因?yàn)闋顟B(tài)的改變會(huì)導(dǎo)致StateListDrawable
切換到具體的Drawable
,而不同的Drawable
具有不同的固有大小族购。true
表示StateListDrawable
的固有大小保持不變壳贪,這時(shí)它的固有大小是內(nèi)部所有Drawabl
e的固有大小的最大值,false
則會(huì)隨著狀態(tài)的改變而改變寝杖。此選項(xiàng)默認(rèn)值為fasle
违施。
android:dither
是否開啟抖動(dòng)效果,開啟此選項(xiàng)可以讓圖片在低質(zhì)量的屏幕上依然獲得較好的顯示效果瑟幕,此選項(xiàng)默認(rèn)值為true
磕蒲。
android:variablePadding
StateListDrawable
的padding
表示是否隨著其狀態(tài)的改變而改變留潦,true
表示會(huì)隨著狀態(tài)的改變而改變,false
表示StateListDrawable
的padding
是內(nèi)部所有Drawable
的padding
的最大值辣往。此選項(xiàng)默認(rèn)值為fasle
兔院,不建議開啟此選項(xiàng)。
<item>
標(biāo)簽表示一個(gè)具體的Drawable
站削,android:drawable
是一個(gè)已有Drawable
的資源id
坊萝,剩下的屬性表示的是View
的各種狀態(tài),每個(gè)item
表示的都是一種狀態(tài)下的Drawable
信息钻哩。
系統(tǒng)會(huì)根據(jù)View
當(dāng)前的狀態(tài)從<selector>
中選擇對(duì)應(yīng)的item
屹堰,每個(gè)item
對(duì)應(yīng)著一個(gè)具體的Drawable
,系統(tǒng)按照從上到下的順序查找街氢,直至查找到第一條匹配的item
。一般來說睦袖,默認(rèn)的item
都應(yīng)該放在<selector>
的最后一條珊肃,并且不附帶任何的狀態(tài),這樣當(dāng)上面的item
都無法匹配View
的當(dāng)前狀態(tài)時(shí)馅笙,系統(tǒng)就會(huì)選擇默認(rèn)的item
伦乔,因?yàn)槟J(rèn)的item
不附帶狀態(tài),所以它可以匹配View
的任何狀態(tài)董习。