1.Drawable簡介java
a.Drawable是一種可在Canvas上進行繪製的對象,即可繪製物。android
b.Drawable類是抽象類,是全部Drawable的基類。繼承關係以下:canvas
c.Drawable使用方式:bash
d.Drawable可經過getIntrinsicWidth()和getIntrinsicHeight()獲取其內部寬/高。ide
注意:並非全部Drawable都有內部寬/高。源碼分析
- 圖片所造成的Drawable的內部寬/高就是圖片的寬/高。
- 顏色所造成的Drawable沒有內部寬/高的概念。
e.Drawable 沒有大小概念。佈局
f.Drawable 使用範圍單一。post
推薦閱讀: 你真的會用Drawable嗎學習
2.Drawable種類動畫
下面分別學習各類Drawable:
a.BitmapDrawable
<bitmap>
,經常使用屬性:bitmap
|- src="@drawable/res_id"
|- antialias="[true | false]"
|- dither="[true | false]"
|- filter="[true | false]"
|- tileMode="[disabled | clamp | repeat | mirror]"
|- gravity="[top | bottom | left | right | center_vertical | | fill_vertical | center_horizontal | fill_horizontal | | center | fill | clip_vertical | clip_horizontal]"
複製代碼
①android:src
:圖片的資源id。
②android:antialias
:是否開啓圖片抗鋸齒。開啓後會讓圖片會更加平滑,同時清楚度下降。
③android:dither
:是否開啓抖動效果。開啓後讓高質量的圖片的比較低質量的屏幕上不失真。
④android:filter
:是否開啓過濾效果。當圖片尺寸被拉伸或壓縮時,開啓過濾效果可保持較好的顯示效果。
⑤android:tileMode
:平鋪模式。可選值的具體含義:
具體效果:
⑥android:gravity
:若位圖比容器小,能夠設置位圖在容器中的相對位置。可選值的具體含義:
①XML定義:
//在Drawable文件夾中建立bg_tilemode_mirror.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:src="@mipmap/ic_launcher"
android:tileMode="mirror"
>
</bitmap>
//在activity_main.xml中設置爲View背景
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_tilemode_mirror"
/>
複製代碼
②Java代碼:
//在MainActivity建立BitmapDrawable
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
BitmapDrawable bitDrawable = new BitmapDrawable(bitmap);
bitDrawable.setDither(true);
bitDrawable.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
//加載到mylayout佈局
LinearLayout myLayout = (LinearLayout) findViewById(R.id.mylayout);
myLayout.setBackgroundDrawable(bitDrawable);
複製代碼
補充實例:BitmapDrawable (可控制對齊平鋪的圖像)
b.NinePatchDrawable
.9
格式的圖片。<nine-patch>
,經常使用屬性:nine-patch
|- src="@drawable/9_png_resid"
|- dither="[true | false]"
|
複製代碼
①android:src
:圖片的資源id。
②android:dither
:是否開啓抖動效果。開啓後讓高質量的圖片的比較低質量的屏幕上不失真。
//在Drawable文件夾中建立bg_nine_patch.xml
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:src="@drawable/box"
>
</nine-patch>
//在activity_main.xml中設置爲EditText背景
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_nine_patch"
/>
複製代碼
c.ShapeDrawable
<shape>
,子節點<corners>
、<gradient>
、<padding>
、<size>
、<solid>
、<stroke>
:<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="[rectangle | oval | line | ring]"
<corners
android:radius="integer"
android:topLeftRaidus="integer"
android:topRightRaidus="integer"
android:bottomLeftRaidus="integer"
android:bottomRightRaidus="integer" />
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="color"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type="[linear | radial | sweep]"
android:useLevel="[true | false]" />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
複製代碼
接下來分別解釋各個節點下屬性含義:
①<shape>
:圖形的形狀。
android:shape
可選值有:
<stroke>
標籤來指定線的寬度和顏色等信息。<stroke>
標籤來指定圓環線的寬度和顏色等信息。②<corners>
:表示shape的四個圓角的角度,只適用於矩形。
android:radius
:爲四個角同事設定相同的角度。優先級比如下4個屬性要低。android:topLeftRadius
:左上角的角度。android:topRightRadius
:右上角的角度。android:bottomLeftRadius
:左下角的角度。android:bottomRightRadius
:右下角的角度。③<gradient>
:漸變效果,與<solid>
純色填充是互相排斥的。
android:angle
:漸變的角度。
android:centerX
:漸變的中心點的X座標。android:centerY
:漸變的中心點的Y座標。android:startColor
:漸變的起始色。android:centerColor
:漸變的中間色。android:endColor
:漸變的結束色。android:gradient
:漸變半徑。僅當**android:type="radial"**時有效。android:useLevel
:通常爲false,當Drawable做StateListDrawable時爲true。android:type
:漸變的類別。可選值:
android:gradient
屬性一塊兒使用。④<padding>
:與四周空白的距離。
⑤<size>
:圖形的固有大小,非最終大小。
android:width
和android:height
分別設定shape的寬/高。⑥<solid>
:純色填充。
android:color
:指定填充的顏色。⑦<stroke>
:描邊。屬性含義:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#a9a6a6" />
<padding
android:bottom="7dp"
android:left="7dp"
android:right="7dp"
android:top="7dp" />
<stroke
android:width="3dip"
android:color="#FFFF00" />
<corners
android:radius="3dp"/>
</shape>
複製代碼
效果圖:
d.LayerDrawable
<layer-list>
,經常使用屬性:layer-list
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
複製代碼
注意:每組 Drawable 由
<item>
節點進行配置,一個layer-list可包含多個item,服從下面item覆蓋上面item的原則。
①android:drawable
:所引用的位圖資源id,若是爲空須要有一個Drawable類型的子節點。
②android:id
:層id。
③android:left
:層相對於容器的左邊距。
④android:right
:層相對於容器的右邊距。
⑤android:top
:層相對於容器的上邊距。
⑥android:bottom
:層相對於容器的下邊距。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher_round"
/>
</item>
<item
android:left="20dp"
android:top="30dp">
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher_round"
/>
</item>
<item
android:left="70dp"
android:top="80dp">
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher_round"
/>
</item>
</layer-list>
複製代碼
效果圖:
補充實例:Drawable子類之——LayerDrawable (圖層疊加)
e.StateListDrawable
<selector>
,經常使用屬性:selector
|-constantSize="[true | false]"
|-dither="[true | false]"
|-variablePadding="[true | false]"
|- item
| |- drawable="@drawable/drawable_id"
| |- state_pressed="[true | false]"
| |- state_focused="[true | false]"
| |- state_selected="[true | false]"
| |- state_hovered="[true | false]"
| |- state_checked="[true | false]"
| |- state_checkable="[true | false]"
| |- state_enabled="[true | false]"
| |- state_activated="[true | false]"
| |- state_window_focused="[true | false]"
|
複製代碼
①<selector>
:
android:constantSize
:固有大小是否隨其狀態的改變而改變。
android:dither
:是否開啓抖動效果。開啓後讓高質量的圖片的比較低質量的屏幕上不失真。android:variblePadding
:其padding是否隨狀態的改變而改變。
②<item>
:
android:drawable
:所引用的位圖資源id。補充實例:探索Android中selector和shape的結合使用
f.LevelListDrawable
<level-list>
,經常使用屬性:level-list
|- item
| |- drawable="@drawable/drawable_id"
| |- maxLevel="integer"
| |- minlevel="integer"
複製代碼
①android:drawable
:引用的位圖資源id。
②android:maxLevel
:對應的最大值,取值範圍爲0~10000,默認爲0。(經常使用)
③android:minlevel
:對應的最小值,取值範圍爲0~10000,默認爲0。
//在Drawable文件夾中建立bg_level.xml
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="1" android:drawable="@drawable/image1" />
<item android:maxLevel="2" android:drawable="@drawable/image2" />
<item android:maxLevel="3" android:drawable="@drawable/image3" />
</level-list>
//在activity_main.xml中設置爲ImageView背景
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg_level"/>
//在MainActivity調用setImageLevel()
ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageLevel(2);
複製代碼
運行結果:ImageView的背景爲image2。
g.TransitionDrawable
<transition>
,經常使用屬性和LayerDrawable相同,再也不贅述。transition
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
複製代碼
//在Drawable文件夾中建立bg_tran.xml
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/image1"/>
<item android:drawable="@drawable/image2"/>
</transition>
//在activity_main.xml中設置爲ImageView背景
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg_tran"/>
//在MainActivity調用startTransition()
ImageView imageView = (ImageView) findViewById(R.id.image);
TransitionDrawable td = (TransitionDrawable) imageView.getDrawable();
td.startTransition(3000);
複製代碼
運行結果:ImageView的背景從image1緩緩切換到image2。
h.InsetDrawable
-表示把一個Drawable嵌入到另一個Drawable的內部,並在四周留一些間距。
與Drawable的padding屬性不一樣:padding表示的是Drawable的內容與Drawable自己的邊距;而InsetDrawable表示的是兩個Drawable與容器之間的邊距。
<inset>
,經常使用屬性:layer-list
|- drawable="@drawable/drawable_id"
|- visible="[true | false]"
|- insetTop="dimension"
|- insetLeft="dimension"
|- insetRight="dimension"
|- insetBottom="dimension"
|
複製代碼
①android:drawable
:所引用的位圖資源id。
②android:visible
:是否留有邊距。
③android:insetTop
:設置距離容器的上邊距。其餘同理。
//在drawable文件夾下建立
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/image"
android:insetBottom="40dp"
android:insetLeft="10dp"
android:insetRight="30dp"
android:insetTop="20dp"
android:visible="true">
</inset>
複製代碼
效果圖:
i.ScaleDrawable
<scale>
,經常使用屬性:scale
|- drawable="@drawable/drawable_id"
|- scaleGravity="[top | bottom | left | right | center_vertical | center_horizontal | center | fill_vertical | fill_horizontal | fill | clip_vertical | clip_horizontal]"
|- scaleWidth="percentage"
|- scaleHeight="percentage"
|
複製代碼
①android:drawable
:所引用的位圖資源id。
②android:scaleGravity
:等同於BitmapDrawable的android:gravity
。
③android:scaleWidth
/android:scaleHeight
:指定Drawable寬/高的縮放比例,以百分比的形式表示。
//在drawable文件夾下建立bg_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_test"
android:scaleGravity="center"
android:scaleHeight="70%"
android:scaleWidth="70%"/>
//在activity_main.xml中設置爲ImageView背景
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg_scale"/>
//在MainActivity調用setLevel()
ImageView imageView = (ImageView) findViewById(R.id.image);
ScaleDrawable scaleDrawable = (ScaleDrawable) imageView.getDrawable();
scaleDrawable.setLevel(1);
複製代碼
j.ClipDrawable
<clip>
,經常使用屬性:scale
|- drawable="@drawable/drawable_id"
|- gravity="[top | bottom | left | right | center_vertical | center_horizontal | center | fill_vertical | fill_horizontal | fill | clip_vertical | clip_horizontal]"
|- clipOrientation="[vertical | horizontal]"
|
複製代碼
①android:drawable
:所引用的位圖資源id。
②android:gravity
:表示對齊方式,須要和clipOrientation一塊兒發揮做用。可選值含義:
③android:clipOrientation
:表示裁剪方向,可選值有水平和豎直。
補充實例:結合Timer作一個簡單的裁剪動畫,固然這個思路也能夠應用到以前學習的縮放ScaleDrawable、LevelListDrawable中來實現一個小動畫。
以上大可能是使用xml來定義一個Drawable,那麼使用java代碼建立方法可參考文章:Android Drawable徹底解析:Drawable子類用法總結,同時這篇文章還講解很多Drawable,好比
ColorDrawable
(1)、AnimationDrawable
(2)、RotateDrawable
(9)、GradientDrawable
(12)、RippleDrawable
(17)、RoundedBitmapDrawable
(15)、DrawerArrowDrawable
(11)、AnimatedStateListDrawable
(5),感興趣能夠了解學習~
3.自定義Drawable
a.Drawable的工做原理的核心是draw():系統調用Drawable的draw()來繪製View的背景或ImageView的圖像。
b.一般沒有必要去自定義Drawable,由於沒法在XML中使用自定義Drawable,這就下降了其使用範圍。
c.建立自定義Drawable,必須重寫其draw()、setAlpha()、setColorFilter()、getOpacity() 等方法。如下爲自定義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 rect = getBounds();
float cx = rect.exactCenterX();
float cy = rect.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 colorFilter) {
mPaint.setColorFilter(colorFilter);
invalidateSelf();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
複製代碼
d.當自定義的Drawable有固有大小時,最好重寫getIntrinsicWidth()和getIntrinsicHeight(),由於它會影響到View的wrap_content佈局。
注意:Drawable的內部大小不等於Drawable的實際大小,後者可經過**getBounds()**得到,通常它和View的尺寸相同。
推薦閱讀:Drawable繪製過程源碼分析和自定義Drawable實現動畫
但願這篇文章對你有幫助~