6.1 Drawable 簡介
Android 中的 Drawable 表示一種可以在 Canvas 上進(jìn)行繪制的抽象的概念亭引,比如顏色和圖片都可以是一個 Drawable。
6.2 Drawable 的分類
6.2.1 BitmapDrawable
BitmapDrawable 表示一張圖片辜羊,可以用原始圖片顯示,也可以用 XML 的方式馒稍。
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/image1" //圖片資源 id
android:antialias="true" //抗鋸齒
android:dither="true" //抖動
android:filter="true"
android:gravity="center"
android:mipMap="false"
android:tileMode="disabled">
</bitmap>
-
android:src
圖片資源 id -
android:antialias
抗鋸齒构罗,開啟后讓圖片變得平滑。 -
android:dither
抖動效果溪北,開啟后圖像在不同屏幕上的顯示效果越逼真桐绒。 -
android:filter
過濾效果,當(dāng)圖片尺寸被拉伸之拨,開啟過濾效果可以保持較好的顯示效果茉继。 -
android:gravity
對圖片在容器中定位。 -
android:mipMap
這一種圖像相關(guān)的處理技術(shù)敦锌,也叫紋理映射馒疹,比較抽象佳簸,默認(rèn) false乙墙,不用深究。 - android:tileMode
- disabled :禁用
- repeat :水平和豎直方向上的平鋪效果
- mirror :水平和豎直方向上的鏡面投影效果
- clamp :四周的像素擴(kuò)散到周圍
6.2 ShapeDrawable
ShapeDrawable 可以理解為通過顏色來構(gòu)造的圖形生均,可以是純色或者具有漸變的圖形听想。需要注意的是<shape>標(biāo)簽創(chuàng)建的 Drawable 其實體類是 GradientDrawable。
-
android:shape
表示圖形的形狀马胧,有四個選項: - rectangle(矩形):默認(rèn)選擇
- oval(橢圓)
- line(橫線):必須通過<stroke>標(biāo)簽來指定線的寬度和顏色等信息
- ring(圓環(huán)):必須通過<stroke>標(biāo)簽來指定線的寬度和顏色等信息
value | Desciption |
---|---|
android:innerRadius | 圓環(huán)的內(nèi)半徑汉买,和 android:innerRadiusRatio 同時存在時,以android:innerRadius為準(zhǔn) |
android:thickness | 圓環(huán)的厚度佩脊,即半徑減去內(nèi)半徑的大小 |
android:innerRadiusRatio | 內(nèi)半徑占整個 Drawable 寬度的比例蛙粘,默認(rèn)值為 9。如果為 n威彰,那么內(nèi)半徑 = 寬度 / n |
android:thicknessRatio | 厚度占整個 Drawable 寬度的比例出牧,默認(rèn)值為 3,,如果為 n歇盼,那么厚度 = 寬度 / n |
android:useLevel | 一般都應(yīng)該使用 false |
<corners>
表示 shape 四個角的角度舔痕,只適用于矩形 shape,用 px 來表示:android:radius —— 為四個角同時設(shè)定相同的角度;
android:topRightRadius —— 設(shè)定右上角的角度伯复;
android:bottomLeftRadius —— 設(shè)定左下角的角度慨代;
android:bottomRightRadius —— 設(shè)定右下角的角度;
<gradient>
它與<soild>標(biāo)簽是互相排斥的啸如,soild 表示純色填充侍匙,gradient 表示漸變效果。android:angle —— 漸變的角度组底,默認(rèn)為 0丈积,其值必須為 45 的背熟,0 表示從左到右债鸡,90 表示從上到下江滨。
android:centerX —— 漸變的中心點的橫坐標(biāo);
android:centerY —— 漸變的中心點的縱坐標(biāo)
android:startColor —— 漸變的起始色
android:centerColor —— 漸變的中間色
android:endColor —— 漸變的結(jié)束色
android:gradientRadius —— 漸變的半徑厌均,僅當(dāng) android:type = “radial” 時有效唬滑。
android:useLevel —— 一般為 false,當(dāng) Drawable 作為 StateListDrawable 使用時為 true棺弊;
android:type —— 漸變的類別晶密,linear(線性漸變)、radial(徑向漸變)模她、sweep(掃描線漸變)
<soild>
純色填充<stroke>
Shape 的描邊android:width —— 描邊的寬度侈净;
android:color —— 描邊的顏色尊勿;
android: dashWidth —— 組成虛線的線段的寬度;
android:dashGap —— 組成虛線的線段之間的間隔畜侦;
<padding>
四個屬性:android:left元扔、top、right旋膳、bottom<size>
shape 的大小澎语,有兩個屬性:android:width、height验懊,表示 shape 的固有大小擅羞,但作為 View 的背景時,還是會被顯示為 View 的大小义图。
6.2.3 LayerDrawable
LayerDrawable 對應(yīng)的 XML 標(biāo)簽是<layer-list> 减俏,通過不同的 Drawable 放置不再通的層上面從而達(dá)到一種疊加后的效果。
<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>
</layer-list>
6.2.4 StateListDrawable
StateListDrawable 對應(yīng)<selector> 標(biāo)簽歌溉,表示 Drawable 的集合垄懂。
android:constantSize
StateListDrawable 的固有大小是否隨著其狀態(tài)的改變而改變骑晶,因為狀態(tài)的改變而切換到具體的 Drawable,為 true 則表示 StateListDrawable 的固有大小是所有 Drawable 最大值并且保持不變草慧,默認(rèn)為 false桶蛔,會改變。android:dither
開啟抖動效果漫谷,默認(rèn)為 true仔雷,開啟后在低質(zhì)量的屏幕上仍有較好的顯示效果。android:variablePadding
StateListDrawable 的 padding 是否隨其狀態(tài)的改變而改變舔示,true 是改變碟婆,默認(rèn)為 false(推薦)。<item>
表示一個具體的 Drawable惕稻。
狀態(tài) | 含義 |
---|---|
android:state_proessed | 表示按下狀態(tài) |
android:state_focused | 表示 View 已經(jīng)獲取了焦點 |
android:state_selected | 表示用戶選擇了焦點 |
android:state_checked | 表示用戶選中了 View竖共,一般適用于 CheckBox 這類。 |
android:state_enabled | 表示 View 當(dāng)前處于可用狀態(tài) |
6.2.5 LeveListDrawable
LeveListDrawable 對應(yīng)于 <level-list> 標(biāo)簽俺祠,表示一個 Drawable 集合公给,根據(jù)其中的 level 來切換對應(yīng)的 Drawable。
- 作為 View 的背景:通過 setLevel 來切換
- 作為 ImageView 的前景 Drawable:通過 ImageView.setImageLevel 來切換蜘渣。
6.2.6 TransitionDrawable
TransitionDrawable 對應(yīng)于<transiton>標(biāo)簽淌铐,用于實現(xiàn)兩個 Drawable 之間的淡入淡出效果。
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bitmap_drawable_clamp"/>
<item android:drawable="@drawable/bitmap_drawable_mirror"/>
</transition>
TransitionDrawable drawable = (TransitionDrawable) button.getBackground();
drawable.startTransition(3000);
6.2.7 InsetDrawable
InsetDrawable 對應(yīng)于<inset>標(biāo)簽蔫缸,它可用將其他 Drawable 內(nèi)嵌到自己當(dāng)中腿准,并可用在四周流出一定的間距。
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="15dp"
android:insetLeft="15dp"
android:insetRight="15dp"
android:insetTop="15dp" >
<shape android:shape="rectangle" >
<solid android:color="#ff0000" />
</shape>
</inset>
6.2.8 ScaleDrawable
ScaleDrawable 對應(yīng)于<scale>標(biāo)簽拾碌,下面案例:顯示 30% 的大小
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/image1"
android:scaleHeight="70%"
android:scaleWidth="70%"
android:scaleGravity="center" />
必須設(shè)置一個比 大于 0 小于 10000 的數(shù)字吐葱,否則無效
ScaleDrawable drawable = (ScaleDrawable) button.getBackground();
drawable.setLevel(1);
6.2.9 ClipDrawable
ClipDrawable 對應(yīng)于<clip>標(biāo)簽,它可以根據(jù)自己當(dāng)前的等級(level)來裁剪另一個 Drawable倦沧。
android:clipOrientation
horizontal:橫向
vertical:豎向
android:gravity
選項 | 含義 |
---|---|
top | 將內(nèi)部的 Drawable 放在容器的頂部唇撬,不改變它的大小它匕。如果為豎直裁剪展融,那么從底部開始裁剪。 |
bottom | 將內(nèi)部的 Drawable 放在容器的底部豫柬,不改變它的大小告希。如果為豎直裁剪,那么從頂部開始裁剪 |
left | 將內(nèi)部的 Drawable 放在容器的左邊烧给,不改變它的大小燕偶。如果為水平裁剪,那么從右邊開始裁剪(默認(rèn)) |
right | 將內(nèi)部的 Drawable 放在容器的右础嫡,不改變它的大小指么。如果為水平裁剪酝惧,那么從左邊開始裁剪 |
center_vertical | 將內(nèi)部的 Drawable 在容器中豎直居中,不改變它的大小伯诬。如果為豎直裁剪晚唇,那么從上下同時開始裁剪 |
fill_vertical | 使內(nèi)部的 Drawable 在豎直方向上填充容器,如果為豎直裁剪盗似。那么僅當(dāng) ClipDrawable 的等級為 0(0 表示 ClipDrawable 被完全裁剪哩陕,既不可見)時,才能有裁剪行為 |
fill_horizontal | 使內(nèi)部的 Drawable 在水平方向上填充容器赫舒,如果為水平裁剪悍及。那么僅當(dāng) ClipDrawable 的等級為 0時,才能有裁剪行為 |
center | 使內(nèi)部的 Drawable 在水平和豎直方向上都居中接癌,不改變它的大小心赶。如果為豎直裁剪,那么從上下同時開始裁剪缺猛,如果為水平裁剪园担,那么從左右同時開始裁剪 |
fill | 使內(nèi)部的 Drawable 在水平和豎直方向上同時填充容器,僅當(dāng) ClipDrawable 的等級為 0時枯夜,才能有裁剪行為 |
clip_vertical | 附加選項弯汰,表示豎直方向裁剪,較少使用 |
clip_horizontal | 附加選項湖雹,表示水平方向裁剪咏闪,較少使用 |
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:drawable="@drawable/image1"
android:gravity="bottom" />
0-10000區(qū)間
ClipDrawable drawable = (ClipDrawable) button.getBackground();
drawable.setLevel(8000);
6.3 自定義 Drawable
很簡單,繼承 Drawable 實現(xiàn)里面的四個方法摔吏。
public class CustomDrawable extends Drawable {
private Paint mPaint;
public CustomDrawable(int color) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
final Rect r = getBounds();
float cx = r.exactCenterX();
float cy = r.exactCenterY();
canvas.drawCircle(cx, cy, Math.min(cx, cy), mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
invalidateSelf();
}
@Override
public int getOpacity() {
// not sure, so be safe
return PixelFormat.TRANSLUCENT;
}
View testCustomDrawable = findViewById(R.id.test_custom_drawable);
CustomDrawable customDrawable = new CustomDrawable(Color.parseColor("#0ac39e"));
testCustomDrawable.setBackgroundDrawable(customDrawable);