一、Drawable簡介
Drawable有很多種,它們都表示一種圖像的概念,但是它們又不全是圖檔,通過顔色也可以構造出各種各樣的圖檔效果。在實際開發中,Drawable常被用來作為view的背景使用。Drawable一般都是通過XML來定義的,也可以用代碼實作,但是比較複雜,在Android中,Drawable是一個抽象類,它是所有Drawable對象的基類,每個具體的Drawable都是它的子類。
Drawable的内部寬高這個參數比較重要,通過getIntrinsicWidth和getIntrinsicHeight這兩個方法可以擷取到他們。但是并不是所有的Drawable都有内部寬高,比如一張圖檔所形成的Drawable,它的内部寬高就是圖檔的寬高,,但是一個顔色所形成的Drawable就沒有内部寬高的概念,注意,Drawable的寬高不等同于它的大小,一般來說,Drawable是沒有大小這個概念的,當用作view的背景時,Drawable會被拉伸至view的等同大小。
二、Drawable的分類
Drawable種類繁多,常見的又BitmapDrawable,ShapeDrawable,LayerDrawable,StateListDrawable等
1.BitmapDrawable
這是最簡單的Drawable了,它表示一張圖檔,在開發中,我們可以直接引用原始的圖檔,也可以用XML方式來描述它通過XML來描述BitmapDrawable可以設定更多的效果
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/bitmapdrawable"
android:antialias="true"
android:dither="true"
android:filter="true"
android:gravity="fill"
android:mipMap="false"
android:tileMode="disabled">
</bitmap>
-
android:src圖檔資源id
- android:antialias 抗鋸齒
- android:dither抖動效果
- android:filter過濾效果
- android:gravity位置
- android:mipMap不常用,設定為false
- android:tileMode當該屬性設定時,gravity屬性會被忽略。disabled關閉平鋪模式;repeat表示水準和豎直方向的平鋪;mirror表示水準和豎直方向鏡面平鋪;clamp:四周的像素會擴充到周圍區域
2.shapeDrawable
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<gradient android:startColor="@color/colorAccent"
android:endColor="@color/colorPrimaryDark"
android:angle="270"
android:type="linear"/>
<padding android:bottom="0dp" android:left="1dp" android:right="2dp" android:top="1dp"/>
<stroke android:color="@color/colorPrimaryDark" android:width="2dp"/>
<size android:width="200dp" android:height="200dp"/>
<solid android:color="@android:color/transparent"/>
</shape>
- shape:圖像形狀:rectangle矩形,oval橢圓,line橫線,ring環形(針對ring這種圖形,有五個特殊屬性,innerRadius圓圈内半徑,和innerRadiusRatio同時存在時,以innerRadius為準;thickness圓環的厚度,和thicknessRatio同時存在,以thickness為準;innerRadiusRatio内半徑占整個Drawable寬度的比例,預設為9,如果是n,那麼半徑 = 寬度/n;thicknessRatio厚度占整個Drawable寬度的比例,預設為3,如果是n,那麼厚度 = 寬度/n;useLevel:一般設定為false)
- corners 一般用來設定矩形的圓角
- gradient 漸變效果,它和solid是互相沖突的(angle:漸變的角度,預設是0,必須是45的倍數;centerX:漸變的中心點的橫坐标;centerY:漸變中心點的縱坐标;startColor:漸變的起始色;centerColor:漸變的中間色;endColor:漸變的結束色;type漸變的類型,linear線性,radial經向,sweep掃描線;gradientRadius:漸變半徑,隻有在radial時有效;useLevel:一般設定為false;)
- padding 表示空白
- stroke 描邊(width:描邊的寬度;color:描邊的顔色;dashWidth:虛線的寬度;dashGap:虛線和虛線間的寬度)
- size 表示大小
- solid 純色填充
3.LayerDrawble
LayerDrawble對應的XML是< layer-list >,它表示一種階層化的Drawble組合。
一個layer-list中可以包含多個item,每個item又是一個Drawble,item的常用屬性有top,bottom,left.right,它們分别代表Drawble相對于view的上下左右偏移量,機關是像素。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/colorAccent"/>
</shape>
</item>
<item
android:bottom="6dp">
<shape android:shape="rectangle">
<color android:color="#fffffff"/>
</shape>
</item>
<item android:bottom="1dp" android:left="1dp" android:right="1dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
</layer-list>
4.StateListDrawable
StateListDrawble對應< selector >标簽
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true"
android:dither="true"
android:variablePadding="true">
<item android:drawable="@color/colorAccent"
android:state_pressed="true"
android:state_focused="true"
android:state_hovered="true"
android:state_selected="true"
android:state_checkable="true"
android:state_checked="true"
android:state_activated="true"
android:state_window_focused="true"
android:state_enabled="true">
</item>
</selector>
- constantSize:StateListDrawble的固有大小是否不随着其狀态的改變而改變得到,false是随着狀态的改變而改變
- dither:是否開啟抖動效果
- variablePadding:StateListDrawble的padding是否不随着其狀态的改變而改變得到,true是随着狀态的改變而改變,false代表padding是内部所有drawble的最大值
- state_pressed:表示按下狀态,比如按鈕别按下還沒有松開的狀态
- state_focused:表示view獲得焦點
- state_hovered:光标是否懸停,通常與focused state相同,它是4.0的新特性
- state_selected:表示使用者選擇了view
- state_checkable元件是否能被check。如:RadioButton是可以被check的
- state_checked表示使用者選中了view,一般用于checkbox
- state_activated被激活(???
- state_window_focused應用程式是否在前台
- state_enabled:view目前處于可用狀态
一般來說預設的item應該放在最後一條且不附帶任何狀态
5.LevelListDrawable
LevelListDrawble對應的标簽是< level-list >,它同樣是表示一個Drawble集合,但是其中每一個Drawble都有一個等級概念,可以通過ImageView 的setImageLevel來改變不同狀态下的圖檔。等級是有範圍的,最小是0,最大10000.
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@color/colorPrimaryDark"
android:maxLevel="1"
>
</item>
<item android:drawable="@color/colorPrimary"
android:maxLevel="0">
</item>
</level-list>
6.TransitionDrawable
TransitionDrawble對應 < transition >,它用于實作兩個Drawble之間的淡入淡出效果
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/colorPrimary" />
<item android:drawable="@color/colorPrimaryDark"/>
</transition>
然後将它設定成view的背景
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:background="@drawable/transition"
/>
然後通過startTrasition和reverseTrasition來實作淡入淡出效果和它的逆過程。
TextView textView = (TextView) findViewById(R.id.tv);
TransitionDrawable drawable = (TransitionDrawable) textView.getBackground();
drawable.startTransition();
7.InsetDrawable
InsetDrawable對應标簽< inset >,它可以将其他Drawable内搶到自己當中,并可以在四周留出一定的間距。當一個view希望自己的背景比自己的實際區域小的時候,可以采用InsetDrawable來實作。
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@color/colorPrimaryDark"
android:insetBottom="19dp"
android:insetLeft="10dp"
android:insetRight="10dp"
android:insetTop="3dp">
</inset>
8.ScaleDrawable
ScaleDrawable 對應标簽 < scale >它根據自己的等級将指定的Drawable 縮放到一定 的比例
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@color/colorPrimaryDark"
android:scaleGravity="fill"
android:scaleHeight="25%"
android:scaleWidth="25%">
</scale>
ScaleDrawable 的級别最大值是10000,那麼沒有縮放效果,ScaleDrawable 的級别越大,内部的Drawable看起來越大,上面的意思是将一張圖縮放到原來75%
9.ClipDrawable
ClipDrawable 對應标簽 < clip > 根據目前等級來裁剪一個Drawble
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@color/colorPrimaryDark"
android:clipOrientation="horizontal"
android:gravity="fill">
</clip>
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiQ3chVEa0V3bT9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwVPjRUT3NWbihmVIFmZWJTWxokbRZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zMzQzN0UTN3ETMzMDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
三、自定義Drawable
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;
}
}
找資料在研究