天天看點

Android的Drawable一、Drawable簡介二、Drawable的分類三、自定義Drawable

一、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>
           
Android的Drawable一、Drawable簡介二、Drawable的分類三、自定義Drawable

三、自定義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;
    }

}
           

找資料在研究