Android各种各样的Drawable-更新中
概述
2D繪圖
通常情況下,我們很少直接使用Drawable的實現類,大部分的情況下還是使用xml的方式進行開發。只有在程序中需要動態的修改drawable的屬性時,才需要使用具體的drawable類型提供的方法。
事實上xml中配置的節點和Drawable的實現類是一一對應的。
Android 在android.graphics.drawable包中提供了了很多Drawable抽象類的實現類:ColorDrawable、GradientDrawable、BitmapDrawable、 NinePatchDrawable、InsetDrawable、ClipDrawable、ScaleDrawable、RotateDrawable、AnimationDrawable、LayerDrawable、LevelListDrawable、StateListDrawable、TransitionDrawable等等
| <animated-rotate> | AnimatedRotateDrawable | A Drawable that can animate a rotation of another Drawable. |
| <animation-list> | AnimationDrawable | An object used to create frame-by-frame animations, defined by a series of Drawable objects, which can be used as a View object’s background. |
| <bitmap> | BitmapDrawable | A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. |
| <clip> | ClipDrawable | A Drawable that clips another Drawable based on this Drawable’s current level value. You can control how much the child Drawable gets clipped in width and height based on the level, as well as a gravity to control where it is placed in its overall container. Most often used to implement things like progress bars. |
| <color> | ColorDrawable | A specialized Drawable that fills the Canvas with a specified color, with respect to the clip region. |
| <inset> | InsetDrawable | A Drawable that insets another Drawable by a specified distance. This is used when a View needs a background that is smaller than the View’s actual bounds. |
| <layer-list> | LayerDrawable | A Drawable that manages an array of other Drawables. These are drawn in array order. |
| <level-list> | LevelListDrawable | A resource that manages a number of alternate Drawables, each assigned a maximum numerical value. |
| <nine-patch> | NinePatchDrawable | A resizeable bitmap, with stretchable areas that you define. |
| <rotate> | RotateDrawable | A Drawable that can rotate another Drawable based on the current level value. The start and end angles of rotation can be controlled to map any circular arc to the level values range. |
| <scale> | ScaleDrawable | A Drawable that changes the size of another Drawable based on its current level value. |
| <selector> | StateListDrawable | Lets you assign a number of graphic images to a single Drawable and swap out the visible item based on state. |
| <shape> | GradientDrawable | Basic method for drawing shapes via XML. |
| <transition> | TransitionDrawable | An extension of <layer-list> that is intended to cross-fade between the first and second layer. The format is exactly the same as <layer-list>. |
http://idunnolol.com/android/drawables.html
ColorDrawable
ColorDrawable 實際上是代表了單色可繪制區域,它包裝了一種固定的顏色,當ColorDrawable被繪制到畫布的時候會使用顏色填充Paint,在畫布上繪制一塊單色的區域。
Xml的方式
android:background=”@drawable/colordrawable_xml”
<TextViewandroid:id="@+id/id_tv_colorDrawableDemo_Xml"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="ColorDrawable-ByXml"android:textColor="@color/bg_black"android:background="@drawable/colordrawable_xml"android:textSize="20sp" />顏色定義在color.xml中,使用時直接引用即可。
<?xml version="1.0" encoding="utf-8"?> <color xmlns:android="http://schemas.android.com/apk/res/android"android:color="@color/skyblue"/>JavaCode的方式
代碼中必須要明確指出透明度(Alpha)代表的數據,即,要加上0x,而且不能把透明度漏掉,否則就是透明的了。
public class ColorDrawableActivity extends AppCompatActivity {private TextView mIdTvColorDrawableDemo;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_color_drawable);mIdTvColorDrawableDemo = (TextView) findViewById(R.id.id_tv_colorDrawableDemo_javaCode);/*** setBackground 在 4.1(API16)之后增加*/if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {/*** 使用Java代碼創建ColorDrawable,* 需要注意的是Android中使用一個int類型的數據表示顏色值,* 通常習慣使用十六進制格式的數據表示顏色值。* 一個int類型包含四個字節,* 分別代表顏色的4個組成部分:透明度(Alpha)、紅(RED)、綠(GREEN)、藍(BLUE),* 每個部分由一個字節(8個bit)表示,取值范圍為0~255。* 在xml中使用顏色時可以省略透明度(Alpha)部分,* 如#ff0000表示紅色。* 但是在代碼中必須要明確指出透明度(Alpha)代表的數據,* 如果省略了就表示完全透明的顏色,也就是說當繪制到畫布上時,看不出有任何效果。*/mIdTvColorDrawableDemo.setBackground(new ColorDrawable(0xffff0000));}} }運行圖
GradientDrawable
GradientDrawable 表示一個漸變區域,可以實現線性漸變、發散漸變和平鋪漸變效果。
在xml文件中使用shape作為根節點來創建GradientDrawable,很多屬性和子節點。
shape
Xml的方式
線性漸變linear
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><!--一個具有漸變區域的Drawable,可以實現線性漸變,發散漸變和平鋪漸變效果核心節點:<gradient/>,有如下可選屬性:startColor:漸變的起始顏色centerColor:漸變的中間顏色endColor:漸變的結束顏色type:漸變類型,可選(linear,radial,sweep), 線性漸變(可設置漸變角度),發散漸變(中間向四周發散),平鋪漸變centerX:漸變中間亞瑟的x坐標,取值范圍為:0~1centerY:漸變中間顏色的Y坐標,取值范圍為:0~1angle:只有linear類型的漸變才有效,表示漸變角度,必須為45的倍數哦gradientRadius:只有radial和sweep類型的漸變才有效,radial必須設置,表示漸變效果的半徑useLevel:判斷是否根據level繪制漸變效果--><gradient android:angle="90"android:centerColor="#00ff00"android:endColor="#0000ff"android:startColor="#ff0000" /><!--描邊--><stroke android:width="3dip"android:color="#fff"android:dashGap="5dip"android:dashWidth="4dip" /> </shape>發散漸變radial
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"android:innerRadius="0dp"android:shape="ring"android:thickness="100dp"android:useLevel="false"><gradient android:centerColor="#FFEB82"android:endColor="#35B2DE"android:gradientRadius="50"android:startColor="#DEACAB"android:type="radial"android:useLevel="false" /></shape>平鋪漸變sweep
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"android:innerRadiusRatio="8"android:shape="ring"android:thicknessRatio="3"android:useLevel="false"><gradient android:centerColor="#FFEB82"android:endColor="#35B2DE"android:startColor="#DEACAB"android:type="sweep"android:useLevel="false" /></shape>引用的Activity
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView android:id="@+id/id_tv_gradientDrawableDemo_Xml1"android:layout_width="200dp"android:layout_height="200dp"android:layout_gravity="center_horizontal"android:layout_margin="10dp"android:background="@drawable/gradient_linear"android:gravity="center"android:text="線性漸變linear-ByXml"android:textColor="@color/bg_black"android:textSize="20sp" /><TextView android:id="@+id/id_tv_gradientDrawableDemo_Xml2"android:layout_width="200dp"android:layout_height="200dp"android:layout_gravity="center_horizontal"android:layout_margin="10dp"android:background="@drawable/gradient_radial"android:gravity="center"android:text="發散漸變radial-ByXml"android:textColor="@color/bg_black"android:textSize="20sp" /><TextView android:id="@+id/id_tv_gradientDrawableDemo_Xml3"android:layout_width="200dp"android:layout_height="200dp"android:layout_gravity="center_horizontal"android:layout_margin="10dp"android:background="@drawable/gradient_sweep"android:gravity="center"android:text="平鋪漸變sweep-ByXml"android:textColor="@color/bg_black"android:textSize="20sp" /></LinearLayout>運行圖
BitmapDrawable
BitmapDrawable 是對bitmap的一種包裝,可以設置它包裝的bitmap在BitmapDrawable區域內的繪制方式,如平鋪填充、拉伸填充或者保持圖片原始大小,也可以在BitmapDrawable區域內部使用gravity指定的對齊方式。
在xml文件中使用bitmap作為根節點來定義BitmapDrawable。
可選屬性說明:
- src:圖片資源~ antialias:是否支持抗鋸齒 filter:是否支持位圖過濾,支持的話可以是圖批判顯示時比較光滑
- dither:是否對位圖進行抖動處理
- gravity:若位圖比容器小,可以設置位圖在容器中的相對位置
- tileMode:指定圖片平鋪填充容器的模式,設置這個的話,gravity屬性會被忽略,有以下可選值: disabled(整個圖案拉伸平鋪),clamp(原圖大小), repeat(平鋪),mirror(鏡像平鋪)
Xml的方式
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:dither="true" android:src="@drawable/ic_launcher" android:tileMode="mirror" />JavaCode的方式
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.os.Build; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView;import com.turing.base.R; import com.turing.base.utils.AlertUtil;public class BitmapDrawableActivity extends AppCompatActivity {private ImageView mIdBitmapDrawableXml;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_bitmap_drawable);mIdBitmapDrawableXml = (ImageView) findViewById(R.id.id_bitmapDrawable_xml);// 通過代碼的方式創建BitmapDrawableBitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.zjl);BitmapDrawable mBitmapDrawable = new BitmapDrawable(mBitmap);mBitmapDrawable.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);mBitmapDrawable.setAntiAlias(true);mBitmapDrawable.setDither(true);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {mIdBitmapDrawableXml.setBackground(mBitmapDrawable); // mIdBitmapDrawableXml.setImageDrawable(mBitmapDrawable);} else {AlertUtil.showDialogWithClose(this, "API<16 不支持setBackground屬性設置");}} }這種方式基本上很啰嗦,很少會用到,了解下就好了
運行圖
InsetDrawable
表示把一個Drawable嵌入到另外一個Drawable的內部,并且在內部留一些間距, 類似與Drawable的padding屬性,但padding表示的是Drawable的內容與Drawable本身的邊距! 而InsetDrawable表示的是兩個Drawable與容器之間的邊距,*當控件需要的背景比實際的邊框 小的時候,比較適合使用InsetDrawable*
比如使用這個可以解決我們自定義Dialog與屏幕之間 的一個間距問題,相信做過的朋友都知道,即使我們設置了layout_margin的話也是沒用的,這個 時候就可以用到這個InsetDrawable了!只需為InsetDrawable設置一個insetXxx設置不同 方向的邊距,然后為設置為Dialog的背景即可!
相關屬性如下:
Xml的方式
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.turing.base.activity.drawable.InsetDrawableActivity"><ImageView android:id="@+id/mIv"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerInParent="true"android:background="@drawable/zjl"android:src="@drawable/insetdrawable_simple" /></RelativeLayout>insetdrawable_simple.xml
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android"android:insetBottom="60dp"android:insetLeft="30dp"android:insetRight="30dp"android:insetTop="60dp"android:visible="true"><!--插入一個藍色的矩形作為演示之用--><shape android:shape="rectangle"><solid android:color="#0000ff" /></shape></inset>JavaCode的方式
public class InsetDrawableActivity extends AppCompatActivity {private ImageView mMIv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_inset_drawable);mMIv = (ImageView) findViewById(R.id.mIv);// JavaCodeInsetDrawable insetDrawable = new InsetDrawable(getResources().getDrawable(R.drawable.zjl), 30, 60, 30, 60);// 設置mMIv.setImageDrawable(insetDrawable);} }NinePathDrawable
如何制作.9圖片
在AS中使用.9圖需要注意:
- .9圖片必須放在drawable目錄下,不能存放在mipmap下
- AS中的.9圖,必須要有黑線,不然編譯都不會通過
使用“點九”圖片處理技術,可以將圖片橫向和縱向同時進行拉伸,以實現在多分辨率下的完美顯示效果。點九圖片在拉伸時仍能保留圖像的漸變質感和圓角的精細度。
Android SDK工具集提供了處理點九圖片的工具,可以通過draw9patch.bat運行,通過這個工具可以很容易把普通的PNG圖片處理成“點九”圖片。
從它的名字也很容易理解“點九”圖的含義,其實相當于把一張PNG圖分成了9個部分(九宮格),分別為4個角,4條邊,以及一個中間區域,4個角是不做拉伸的,所以還能一直保持圓角的清晰狀態,而2條水平邊和2條垂直邊分別只做水平和垂直拉伸,所以不會出現邊框被拉粗的情況,只有中間用黑線指定的區域做拉伸,通過這種處理方式圖片才不會失真。如圖6-5所示,對4條黑線分別做了注釋。左邊和上邊的黑線形成的矩形區域是圖片的拉伸區域,下邊和右邊形成的矩形區域是內容所在的區域。黑線可以是連續的也可以是不連續的,不過為了達到最好的顯示效果,最好使用連續的黑線。
使用了*.9.png圖片技術后,只需要采用一套界面切圖去適配不同的分辨率,而且大幅減少安裝包的大小。
要點: 左上拉伸 右下內容
在xml文件中使用使用nine-patch作為根節點創建NinePatchDrawable。同時,也可以使用bitmap包裝點九圖片,android FrameWork會根據android:src屬性設置的圖片類型來生成對應的drawable。
不過這樣使用基本也是太啰嗦了,直接設置背景圖就可以了,這里只是說明下可以這樣使用~
xml定義NinePatchDrawable:
<!--pic9.xml--> <!--參數依次為:引用的.9圖片,是否對位圖進行抖動處理--> <?xml version="1.0" encoding="utf-8"?> <nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/dule_pic" android:dither="true"/>使用Bitmap包裝.9圖片:
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/dule_pic" android:dither="true"/>最后,需要指出的是,Android雖然可以使用Java代碼創建NinePatchDrawable,但是極少情況會那么做,主要的原因是由于Android SDK會在編譯工程時對點九圖片進行編譯,形成特殊格式的圖片。使用代碼創建NinePatchDrawable時只能針對編譯過的點九圖片資源,對于沒有編譯過的點九圖片資源都當做BitmapDrawable對待。在使用點九圖片時需要注意的是,點九圖只能適用于拉伸的情況,對于壓縮的情況并不適用,如果需要適配很多分辨率的屏幕時需要把點九圖做的小一點。
ClipDrawable
ClipDrawable 是對一個Drawable進行剪切操作,可以控制這個drawable的剪切區域,以及相相對于容器的對齊方式,android中的進度條就是使用一個ClipDrawable實現效果的,它根據level的屬性值,決定剪切區域的大小。
在xml文件中使用clip作為根節點定義ClipDrawable。
需要注意的是ClipDrawable是根據level的大小控制圖片剪切操作的,官方文檔的note中提到:The drawable is clipped completely and not visible when the level is 0 and fully revealed when the level is 10,000。也就是level的大小從0到10000,level為0時完全不顯示,為10000時完全顯示。是用Drawable提供的setLevel(int level)方法來設置剪切區域。
- clipOrietntion:設置剪切的方向,可以設置水平和豎直2個方向
- gravity:從那個位置開始裁剪
- drawable:引用的drawable資源,為空的話需要有一個Drawable類型的子節點 .
如果沒有android:drawable屬性,必須要設置一個任意類型的drawable作為子節點
核心:通過代碼修改ClipDrawable的level的值!Level的值是0~10000!
Code
在主布局文件中設置一個ImageView,將src設置為clipDrawable! 記住是src,如果你寫成了blackground的話會報空指針
activity_clip_drawable_actvity.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageView android:id="@+id/id_iv_clipdrawable"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/clipdrawable_xml"/></LinearLayout>clipdrawable_xml.xml
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android"android:clipOrientation="horizontal"android:drawable="@drawable/zjl"android:gravity="left"/>第一種方式 推薦
public class ClipDrawableActvity extends AppCompatActivity {private ImageView mIdIvClipdrawable;private ClipDrawable clipDrawable;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == 0x110) {// level 增加clipDrawable.setLevel(clipDrawable.getLevel() + 500);Message message = Message.obtain();message.what = 0x110;handler.sendMessageDelayed(message, 500);if (clipDrawable.getLevel() > 10000) {handler.removeMessages(0x110);}}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_clip_drawable_actvity);mIdIvClipdrawable = (ImageView) findViewById(R.id.id_iv_clipdrawable);clipDrawable = (ClipDrawable) mIdIvClipdrawable.getDrawable();handler.sendEmptyMessage(0x110);}}第二種方式:
public class ClipDrawableActvity extends AppCompatActivity {private ImageView mIdIvClipdrawable;private ClipDrawable clipDrawable;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == 0x110) {// level 增加clipDrawable.setLevel(clipDrawable.getLevel() + 500);}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_clip_drawable_actvity);mIdIvClipdrawable = (ImageView) findViewById(R.id.id_iv_clipdrawable);clipDrawable = (ClipDrawable) mIdIvClipdrawable.getDrawable();// 開啟定時任務final Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {handler.sendEmptyMessage(0x110);// 到達最大值后,取消任務if (clipDrawable.getLevel() > 10000) {timer.cancel();}}}, 0, 500);}}運行圖
ScaleDrawable
ScaleDrawable是對一個Drawable進行縮放操作,可以根據level屬性控制這個drawable的縮放比率,也可以設置它在容器中的對齊方式。
在xml文件中使用scale作為根節點來創建RotateDrawable。
android:drawable 指定drawable資源,如果不設置該屬性,也可以定義drawable類型的子標簽
android:scaleHeight 設置可縮放的高度,用百分比表示,格式為XX%,
0%表示不做任何縮放,50%表示只能縮放一半android:scaleWidth 設置可縮放的寬度,用百分比表示,格式為XX%,
0%表示不做任何縮放,50%表示只能縮放一半android:scaleGravity 設置drawable縮放后的位置,取值和bitmap標簽的一樣,默認值是left
http://stackoverflow.com/questions/5507539/android-scaledrawable-doesnt-seems-to-work
首先聲明一下,通過xml的方式 無效了。。。。。。
Code
<ImageView android:id="@+id/id_show_scaleDrawable"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/scaledrawable_simple"/>scaledrawable_simple.xml
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/face"android:scaleGravity="center"android:scaleHeight="100%"android:scaleWidth="100%" />sorry,這樣行不通了。 我們用代碼的方式來創建吧
public class ScaleDrawableActivity extends AppCompatActivity {private ImageView mIdShowScaleDrawable;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scale_drawable);mIdShowScaleDrawable = (ImageView) findViewById(R.id.id_show_scaleDrawable);Resources res = getResources();BitmapDrawable bd = (BitmapDrawable) res.getDrawable(R.drawable.zjl);Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(),(int) (bd.getIntrinsicHeight() * 0.7),(int) (bd.getIntrinsicWidth() * 0.7),false);mIdShowScaleDrawable.setImageBitmap(b);} } <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.turing.base.activity.drawable.ScaleDrawableActivity"><ImageView android:id="@+id/id_show_scaleDrawable"android:layout_width="wrap_content"android:layout_height="wrap_content"/> </RelativeLayout>RotateDrawable
RotateDrawable 是對一個Drawable進行旋轉操作,可以根據level屬性控制這個drawable旋轉角度,也可以設置相對于它所在容器的對齊方式。
用來對Drawable進行旋轉,也是通過setLevel來控制旋轉的,最大值也是:10000
在xml文件中使用rotate作為根節點來定義RotateDrawable.
- fromDegrees:起始的角度,,對應最低的level值,默認為0
- toDegrees:結束角度,對應最高的level值,默認360
- pivotX:設置參照點的x坐標,取值為0~1,默認是50%,即0.5
- pivotY:設置參照點的Y坐標,取值為0~1,默認是50%,即0.5 ps:如果出現旋轉圖片顯示不完全的話可以修改上述兩個值解決!
- drawable:設置位圖資源
- visible:設置drawable是否可見!
Code
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/zjl"android:pivotX="50%"android:pivotY="50%"android:fromDegrees="180"/>AnimationDrawbale
詳見本人另外博客
AnimationDrawable類:幀動畫類
AnimationDrawable 對應于Android中的幀動畫,就是把一系列的drawable按照一定的順序,一幀一幀的播放,并且可以使用android:oneshot屬性設置是否循環播放。
在xml文件中使用animation-list作為根節點定義AnimationDrawable,使用item設置需要播放的每一幀使用的drawable資源,以及每一幀持續的時常。
定義了AnimationDrawable之后需要主動調用AnimationDrawable的start播放動畫,需要注意的是,當我們在Activity的oncreate方法中調用start方法時會沒有任何效果,那是因為view還沒有初始化完成,無法播放動畫,所以需要使用handler來延遲播放動畫,具體實現代碼如下:
mHandler.postDelayed(new Runnable() {@Overridepublic void run() {((AnimationDrawable)mDrawable).start();} }, 1000);LayerDrawable
LayerDrawable 管理一組drawable,每個drawable都處于不同的層,當它們被繪制的時候,按照順序全部都繪制到畫布上。雖然這些drawable會有交差或者重疊的區域,但是它們是位于不同的層,彼此之間不會影響。
在xml文件中使用layer-list作為根節點來定義LayerDrawable,通過item子節點定義每一層的drawable,layer-list沒有屬性節點,只包含item子節點。
- drawable:引用的位圖資源,如果為空徐璈有一個Drawable類型的子節點
- left:層相對于容器的左邊距
- right:層相對于容器的右邊距
- top:層相對于容器的上邊距
- bottom:層相對于容器的下邊距
- id:層的id
Code
下面我們通過一個自定義的Seekbar來演示下如何使用:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.turing.base.activity.drawable.LayerDrawableActivity"><SeekBar android:layout_width="match_parent"android:layout_height="wrap_content"android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"android:indeterminateOnly="false"android:maxHeight="10dp"android:minHeight="5dp"android:progressDrawable="@drawable/layerxml"android:thumb="@drawable/shape_slider"/></RelativeLayout>layerxml.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"><item><shape android:shape="rectangle"><corners android:radius="50dp" /><solid android:color="#C2C2C1" /></shape></item><item><clip><shape><corners android:radius="50dp" /><solid android:color="#BCDA73" /></shape></clip></item></layer-list>shape_slider.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="#2C96ED"/><size android:height="30dp" android:width="30dp"/> </shape>主Activity
public class LayerDrawableActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_layer_drawable);} }運行圖
LevelListDrawable
管理一組drawable,每一個drawable都對應一個level范圍,當它們被繪制的時候,根據level屬性值選取對應的一個drawable繪制到畫布上。
在xml文件中使用level-list作為根節點來定義LevelListDrawable,通過item子節點定義每一層的drawable,level-list沒有屬性節點,只包含item子節點。
item可供設置的屬性如下:
- drawable:引用的位圖資源,如果為空需要有一個Drawable類型的子節點
- minlevel:level對應的最小值
- maxlevel:level對應的最大值
通過shapeDrawable畫圓,一式五份,改下寬高即可:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="#2C96ED"/><size android:height="20dp" android:width="20dp"/> </shape>接著到LevelListDrawable,這里我們設置五層:
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/shape_circle1" android:maxLevel="2000"/><item android:drawable="@drawable/shape_circle2" android:maxLevel="4000"/><item android:drawable="@drawable/shape_circle3" android:maxLevel="6000"/><item android:drawable="@drawable/shape_circle4" android:maxLevel="8000"/><item android:drawable="@drawable/shape_circle5" android:maxLevel="10000"/></level-list>引用
android:src 一定要是src ,不能使background,否則會拋出空指針異常。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageView android:id="@+id/id_iv_levellist"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/levellist" /> </RelativeLayout> import android.graphics.drawable.LevelListDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView;import com.turing.base.R;public class LevelListDrawableActivity extends AppCompatActivity {private ImageView imageView;private LevelListDrawable levelListDrawable;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0x110:if (levelListDrawable.getLevel() > 10000) {// 設置為0 ,循環展示levelListDrawable.setLevel(0);imageView.setImageLevel(0);//移除消息// handler.removeMessages(0x110);}imageView.setImageLevel(levelListDrawable.getLevel() + 2000);Message message = Message.obtain();message.what = 0x110;handler.sendMessageDelayed(message, 500);break;default:break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_level_list_drawable);imageView = (ImageView) findViewById(R.id.id_iv_levellist);levelListDrawable = (LevelListDrawable) imageView.getDrawable();imageView.setImageLevel(0);handler.sendEmptyMessage(0x110);} }StateListDrawable
StateListDrawable管理一組drawable,每一個drawable都對應著一組狀態,狀態的選擇類似于java中的switch-case組合,按照順序比較狀態,當遇到匹配的狀態后,就返回對應的drawable,因此需要把最精確的匹配放置在最前面,按照從精確到粗略的順序排列。
StateListDrawable在Android中使用的非常廣泛,所有控件的背景基本上都使用了StateListDrawable,比如按鈕就具有很多狀態,按下狀態、選中狀態、默認狀態、禁用狀態等等,像這樣在不用的狀態下顯示效果不一樣的時候,就是需要使用StateListDrawable的時候。
在xml文件中使用selector作為根節點來定義StateListDrawable,并使用item定義不同狀態下的drawable。
TransitionDrawable
TransitionDrawable 是LayerDrawable的子類,不過它只負責管理兩層drawable,并且提供了一個透明度變化的動畫,可以控制從一層drawable過度到另外一層drawable的動畫效果。
在xml文件中使用transition作為根節點來定義TransitionDrawable,通過item子節點定義兩層使用的drawable
優秀的文章1
優秀的文章2
總結
以上是生活随笔為你收集整理的Android各种各样的Drawable-更新中的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 干货三:CountDownTimer倒计
- 下一篇: Android通用流行框架汇总