本文已經收錄到個人Github我的博客,歡迎大佬們光臨寒舍:php
個人GIthub博客java
Drawable
簡介Drawable
分類Drawable
Drawable
種類繁多,它們都表示一種圖像的概念,可是它們不全是圖片。在實際開發中,Drawable
常常被用來做爲View
的背景使用。android
Drawable
能夠方便咱們作出一些特殊的UI效果,這一點在UI相關的開發工做中極爲重要。面對UI設計師設計出來的各式各樣的按鈕點擊效果,動態效果,漸變效果,好看是好看,咱們程序員每每會咆哮:"你舒服了,咱們呢!!"別慌,學好Drawable
,你會對各類效果信手拈來,瞭然於胸,成竹在胸!!git
並且,Drawable
在開發中也有本身的優勢:程序員
使用簡單,成本低於自定義Viewgithub
非圖片類型的Drawable
佔用空間較小,對於減小APK大小有所裨益canvas
綜上,掌握好Drawable
,走遍天下也不怕!(jia de)swift
Drawable
簡介Q1:Drawable
類是抽象類,是全部Drawable的基類。繼承關係以下:ruby
Q2:Drawable
使用方式:bash
- 普通控件(非ImageView)是設置
background
- ImageView是設置
src
Q3:內部寬高了解多少?
getIntrinsicWidth()
和getIntrinsicHeight()
注意:
- 並非全部
Drawable
都有內部寬/高- 圖片所造成的
Drawable
的內部寬/高就是圖片的寬/高。- 顏色所造成的
Drawable
默認狀況下沒有內部寬/高的概念(除非指定size)。- 內部寬高不等於大小,
Drawable
沒有大小概念Drawable
被用做background
的時候,自動被拉伸到View同等大小;Drawable
被用做src
的時候,存放原圖大小比例,不會被拉伸
Drawable
種類BitmapDrawable
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]" 複製代碼
src
:圖片的資源idantialias
:是否開啓圖片抗鋸齒。開啓後會讓圖片會更加平滑,同時清晰度下降不多,應該開啓。dither
:是否開啓抖動效果。開啓後讓高質量的圖片的在低質量的屏幕上顯示不失真,應該開啓。filter
:是否開啓過濾效果。當圖片尺寸被拉伸或壓縮時,開啓後可保持較好的顯示效果,應該開啓tileMode
:平鋪模式。開啓後gravity
會失效;可選值的具體含義:
可選項 含義 disable 默認值,關閉平鋪模式 mirror 在水平和垂直方向的鏡面投影效果 repeat 在水平和垂直方向的平鋪效果 clamp 圖片四周像素會擴散到其餘區域 具體效果:
![]()
gravity
:若位圖比容器小,能夠設置位圖在容器中的相對位置。可選值的具體含義:![]()
- 使用方法:如下兩種方法效果相同,圖見以前截圖中所示的mirror狀況。
a.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" /> 複製代碼
b.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); 複製代碼
NinePatchDrawable
.9
格式的圖片BitmapDrawable
同樣NinePatchDrawable
,建議使用XML定義,代碼見下。//在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" />
複製代碼
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" />
複製代碼
接下來分別解釋各個節點下屬性含義:
Q1 shape
:圖形的形狀,可選值有:
注意:必須經過
stroke
標籤來指定線的寬度和顏色等信息。
- 注意:必須經過
stroke
標籤來指定圓環線的寬度和顏色等信息。- 圓環還有額外幾個屬性,以下圖所示:
![]()
Q2 corners
:表示shape的四個圓角的角度,只適用於矩形。
radius
:爲四個角同時設定相同的角度。優先級比如下4個屬性要低。topLeftRadius
:左上角的角度topRightRadius
:右上角的角度bottomLeftRadius
:左下角的角度bottomRightRadius
:右下角的角度Q3:gradient
:漸變效果,與solid
純色填充是互斥的。
angle
:漸變的角度。
- 默認爲0
- 值必須爲45的倍數。
- 0表示從左到右,90表示從下到上。
centerX
:漸變的中心點的X座標centerY
:漸變的中心點的Y座標startColor
:漸變的起始色centerColor
:漸變的中間色endColor
:漸變的結束色gradientRadius
:漸變半徑。僅當android:type="radial"
時有效useLevel
:通常爲false,當Drawable做StateListDrawable
時爲truetype
:漸變的類別。可選值:
linear
(線性漸變):默認radial
(輻射漸變):須要配合android:gradientRadius
屬性一塊兒使用。sweep
(掃描線漸變):![]()
padding
:與四周空白的距離。size
:圖形的固有大小,非最終大小
android:width
和android:height
分別設定shape的寬/高。
solid
:純色填充。
android:color
:指定填充的顏色。
stroke
:描邊。屬性含義:stroke的屬性 | 做用 |
---|---|
width | 描邊的寬度 |
color | 描邊的顏色 |
dashWidth | 虛線的寬度 |
dashGap | 虛線的空隙的間隔 |
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的原則。
A.drawable
:所引用的位圖資源id,若是爲空須要有一個Drawable類型的子節點。
B.id
:層id。
C.left
:層相對於容器的左邊距。
D.right
:層相對於容器的右邊距。
E.top
:層相對於容器的上邊距。
F.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>
複製代碼
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]" | 複製代碼
A.selector
:
constantSize
:固有大小是否不變。
默認爲false,表示固有大小會隨着狀態的改變而改變。
設爲true,則表示固有大小是固定值,是內部全部Drawable的固有大小中的最大值。
dither
:是否開啓抖動效果。開啓後讓高質量的圖片的比較低質量的屏幕上不失真。默認開啓。variblePadding
:其padding是否隨狀態的改變而改變。
- 默認爲false,表示padding是固定值,是其內部全部Drawable的padding中的最大值。
- 爲true,則表示padding會隨着狀態的改變而改變。
B.item
:
drawable
:所引用的位圖資源id。狀態 | 含義 |
---|---|
state_pressed(經常使用) | 按下狀態 |
state_focused | 已經獲取了焦點 |
state_selected | 選擇了View |
state_checked | 適用於checkBox |
state_enabled | 表示可用狀態 |
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="false" android:dither="true" android:variablePadding="false">
<item android:drawable="@drawable/red_bg" android:state_pressed="false" />
<item android:drawable="@color/black_bg" android:state_pressed="true" />
</selector>
複製代碼
LevelListDrawable
Drawable
level-list
,經常使用屬性:level-list
|- item
| |- drawable="@drawable/drawable_id"
| |- maxLevel="integer"
| |- minlevel="integer"
複製代碼
drawable
:引用的位圖資源id。maxLevel
:對應的最大值,取值範圍爲0~10000,默認爲0。(經常使用)minlevel
:對應的最小值,取值範圍爲0~10000,默認爲0。
使用方法:不管是用xml仍是代碼實現,若做爲View背景,都須要在Java代碼中調用setLevel()
方法;若做爲ImageView前景,須要調用setImageLevel()
。
加載規則:當某item的android:maxLevel 等於 setLevel所設置的數值時就會被加載。若都沒有匹配的則都不顯示。
實例:
//在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。
TransitionDrawable
transition
,經常使用屬性和LayerDrawable
相同,再也不贅述。transition
|- item
| |- drawable="@drawable/drawable_id"
| |- id="@+id/xxx_id"
| |- top="dimension"
| |- left="dimension"
| |- right="dimension"
| |- bottom="dimension"
|
複製代碼
使用方法:不管是用xml仍是代碼實現,若做爲View背景,都須要在Java代碼中調用startTransition()
方法才能啓動兩層間的切換動畫,也能夠調用reverseTransition()
方法反方向切換。
實例:
//在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的src
<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_tran" android:src="@drawable/bg_tran"/>
//在MainActivity調用startTransition()
ImageView imageView = (ImageView) findViewById(R.id.image);
TransitionDrawable td = (TransitionDrawable) imageView.getDrawable();
TransitionDrawable td2 = (TransitionDrawable) imageView.getBackground();
td.startTransition(3000);
td2.startTransition(3000);
複製代碼
運行結果:ImageView的背景從image1緩緩切換到image2。
InsetDrawable
與Drawable的padding屬性不一樣:padding表示的是Drawable的內容與Drawable自己的邊距;而InsetDrawable表示的是Drawable與容器之間的邊距。
inset
,經常使用屬性:inset
|- drawable="@drawable/drawable_id"
|- visible="[true | false]"
|- insetTop="dimension"
|- insetLeft="dimension"
|- insetRight="dimension"
|- insetBottom="dimension"
|
複製代碼
drawable
:所引用的位圖資源id。visible
:是否留有邊距。(經測試,發現設置true/false效果同樣....)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>
複製代碼
效果圖:
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"
|
複製代碼
drawable
:所引用的位圖資源id。scaleGravity
:等同於BitmapDrawable的android:gravity
。scaleWidth
/android:scaleHeight
:指定Drawable寬/高的縮放比例,以百分比的形式表示。
setLevel()
方法控制Drawable等級。
- level取值範圍爲0~10000
- 默認值爲0:表示不可見;1~10000:表示可見
//在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);
複製代碼
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]"
|
複製代碼
drawable
:所引用的位圖資源id。gravity
:表示對齊方式,須要和clipOrientation一塊兒發揮做用。可選值含義:![]()
clipOrientation
:表示裁剪方向,可選值有水平和豎直。
setLevel()
方法控制可見區大小。
- level取值範圍爲0~10000。
- 0:表示徹底裁剪,即不可見;10000:表示不裁剪。
- level越大可見區越大。
draw()
:系統調用Drawable的draw()
來繪製View的背景或ImageView的圖像。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;
}
}
複製代碼
getIntrinsicWidth()
和getIntrinsicHeight()
,由於它會影響到View的wrap_content佈局。注意:Drawable的內部大小不等於Drawable的實際大小,後者可經過
getBounds()
得到,通常它和View的尺寸相同。
恭喜你!已經看到這裏了,相信你已經對Drawable
有必定的看法了!本文只是介紹了Drawable
中經常使用的類型,並無徹底列出全部Drawable
的類型,並且只是介紹了XML
的建立。
可是,筆者也給好奇心強的讀者準備了一些乾貨(一篇博客),裏面詳細介紹了Drawable的各類類型,各類建立方法,總的來講仍是寫得比較不錯的。指路:Drawable子類用法總結.
下面展現下本文還沒來得及贅述的Drawable
:
若是文章對您有一點幫助的話,但願您能點一下贊,您的點贊,是我前進的動力
本文參考連接: