Android開發中,我們經常會用到Color或Drawable,有時他們是可以混用的,有時卻有嚴格的區別。
Drawable
體系結構
Drawable是可繪制物件的一般抽象。與View不同,Drawable上沒有事件和交互方法。我們經常會自定義View來實現一些復雜或絢麗的UI效果,其實也可以自定義Drawable來實現。
Drawable本身是一個抽象類,我們一般使用的是它的子類,都在android.graphics.drawable包下。有Bitmap、Levels、NinePatch、Scale、Shape、Layers、States等等。
原理
draw(Canvas canvas)Drawable必須附在一個View上,繪制成什么樣子,setBounds()來決定大小,由view的draw方法來繪制Drawable的子類。
圓角和圓形Drawable(頭像)
自定義Drawable很容易實現圓角和圓形圖片,先看效果圖: 
/** * 圓角圖片 * Created by dengpan on 16/4/21. */ public class RoundRectImageDrawable extends Drawable { private RectF rectF; private Paint mPaint; private Bitmap bitmap; public RoundRectImageDrawable(Bitmap bitmap) { this.bitmap = bitmap; //表示圖片太大,則填充。TileMode還有repeat、mirror,表示重復 BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setShader(bitmapShader); rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); rectF = new RectF(left, top, right, bottom); } @Override public void draw(Canvas canvas) { //60表示圓角的半徑 canvas.drawRoundRect(rectF, 60, 60, mPaint); } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter colorFilter) { } @Override public int getOpacity() { return 0; } //設置下面兩個方法,保證原圖可以完整的顯示出來。 @Override public int getIntrinsicWidth() { return bitmap.getWidth(); } @Override public int getIntrinsicHeight() { return bitmap.getHeight(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
下面是圓形Drawable:
/** * 圓形圖片(頭像) * Created by dengpan on 16/4/21. */ public class CircleDrawable extends Drawable { private int mWidth; private RectF rectF; private Paint mPaint; private Bitmap bitmap; public CircleDrawable(Bitmap bitmap) { this.bitmap = bitmap; BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setShader(bitmapShader); rectF = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); mWidth = Math.min(bitmap.getWidth(), bitmap.getHeight()); } @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); rectF = new RectF(left, top, right, bottom); mWidth = (int) Math.min(rectF.width(), rectF.height()); } @Override public void draw(Canvas canvas) { canvas.drawCircle(rectF.left + mWidth / 2, rectF.top + mWidth / 2, mWidth / 2, mPaint); } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter colorFilter) { } @Override public int getOpacity() { return 0; } //設置了下面兩個方法的返回值,才能正常的顯示完整的圓形頭像,不然頭像太大,就截取了左上角部分。 @Override public int getIntrinsicWidth() { return mWidth; } @Override public int getIntrinsicHeight() { return mWidth; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
調用方法:
Bitmap b = BitmapFactory.decodeResource(getResources(), R.mipmap.cute); //圓角Drawable imageView1.setImageDrawable(new RoundRectImageDrawable(b)); //圓形Drawable imageView2.setImageDrawable(new CircleDrawable(b));
- 1
- 2
- 3
- 4
- 5
Shape
Shape類型是用來繪制幾何圖形的,易用而且輕量化。一般使用XML來使用,放在res/drawable目錄下。
使用
<shape>標簽定義的是GradientDrawable
Shape類是個抽象類,draw(Canvas canvas, Paint paint)必須實現,onResize(float width, float height)也是非常重要的方法。它有五種子類。
| 子類 | 說明 |
|---|---|
| RectShape | 矩形、直角矩形、圓角矩形 |
| OvalShape | 橢圓形、圓形 |
| PathShape | 線形、環形 |
| Ring、Line | 環形、環形進度條、線形、實線、虛線 |
| ArcShape | 弧形 |
Shape的通用屬性:
| 屬性 | 值說明 |
|---|---|
| shape | 根標簽。shape:[“rectangle”,”oval”,”ring”,”line”] ring有innerRadius[內環半徑]、innerRadiusRatio、thickness[厚度]、thicknessRatio、useLevels等屬性 |
| corners | radius、topLeftRadius、topRightRadius… |
| gradient | 漸變色。startColor,centerColor、endColor、angle(由type決定,如果是linear類型,則表示從什么角度漸變)、type[“linear”、”radial”、”sweep”]… |
| padding | drawable中的屬性。left、top、right、bottom |
| size | width、height,決定Shape的寬高,不設置則由view的寬高決定 |
| solid | color 填充色。 |
| stroke | 邊角線:width、color、dashWidth(虛線寬度)、dashGap(虛線間隔)。 |
例如:很容易做一個圓角的按鈕背景圖,不需要美工作圖。
<?xml version="1.0" encoding="utf-8"?> <!-- shape屬性設置形狀。 這里是矩形,也可以設置圓形(oval)--> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 圓角半徑 --> <corners android:radius="8dp" /> <!-- 填充顏色 --> <solid android:color="#da87ef" /> <!-- 大小--> <size android:width="100dp" android:height="100dp" /> <!-- padding--> <padding android:bottom="8dp" android:left="8dp" android:right="8dp" android:top="8dp" /> <!-- 邊線。這里設置的虛線。shape="line"這個是必須的屬性,也可以是唯一的屬性。 --> <stroke android:width="1dp" android:color="@color/gray" android:dashGap="1dp" android:dashWidth="1dp" /> <!-- gradient --> <!--<gradient android:centerColor="@color/green" android:endColor="@color/yellow" android:gradientRadius="50dp" android:startColor="@color/blue" android:type="radial" />--> </shape>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
效果如下: 
PathShape和ArcShape
我們可以使用代碼實現Path和Arc類型的drawable,繪制不同的幾何形狀。 
ShapeDrawable shapeDrawable = null; Path p = new Path(); p.moveTo(50,0); p.lineTo(0,50); p.lineTo(50,100); p.lineTo(100,50); p.lineTo(50,0); p.close(); PathShape ps = new PathShape(p,100,100); shapeDrawable = new ShapeDrawable(ps); shapeDrawable.setBounds(0,0,100,150); shapeDrawable.getPaint().setStyle(Paint.Style.FILL); shapeDrawable.getPaint().setColor(Color.CYAN); imageViewShapePath.setBackgroundDrawable(shapeDrawable); //Arc shape ArcShape arcShape = new ArcShape(225,270);//初始180度,逆時針旋轉270度。0度在右手水平位置。 shapeDrawable = new ShapeDrawable(arcShape); shapeDrawable.setBounds(0,0,200,200); shapeDrawable.getPaint().setStyle(Paint.Style.FILL); shapeDrawable.getPaint().setColor(Color.BLUE); imageViewShapeArc.setBackgroundDrawable(shapeDrawable); arcShape = new ArcShape(45,270);//初始180度,旋轉270度。0度在右手水平位置。 shapeDrawable = new ShapeDrawable(arcShape); shapeDrawable.setBounds(0,0,200,200); shapeDrawable.getPaint().setStyle(Paint.Style.STROKE); shapeDrawable.getPaint().setColor(Color.RED); imageViewShapeRing.setBackgroundDrawable(shapeDrawable);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
ShapeDrawable和ShapeDrawable.ShaderFactory
Shapedrawable直接在Java代碼中使用。 Shape對象放入ShapeDrawable中,ShapeDrawables設置畫筆樣式。
Drawable尺寸變化時調用ShapeDrawable.ShaderFactory產生的Shader。 BitmapShader、ComposeShader、LinearGradient、RadialGradient、SweepGradient。
//BitmapShader shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() { @Override public Shader resize(int width, int height) { return new BitmapShader(b, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); } }); //LinearGradient shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() { @Override public Shader resize(int width, int height) { return new LinearGradient(0,0,width,height, new int[]{ //可以設置多個顏色漸變,可以任意多個顏色 Color.RED,Color.BLACK,Color.BLUE },null, Shader.TileMode.CLAMP); } }); //SweepGradient 注意:最后兩個參數的數量要一致 shapeDrawable.setShaderFactory(new ShapeDrawable.ShaderFactory() { @Override public Shader resize(int width, int height) { return new SweepGradient(width/2,height/2, new int[]{ Color.RED,Color.YELLOW,Color.BLUE, Color.CYAN },new float[]{0.1f,0.3f,0.7f,1.0f}); } });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
圖片相關Drawable
BitmapDrawable
BitmapDrawable是對bitmap的一種封裝。它可以設置繪制方式,使圖片平鋪、拉伸或保持圖片原始大小。比如一些需要重復的圖片,可以讓美工提供很小的圖片,我們使用BitmapDrawable來進行重復渲染。
| 屬性 | 說明 |
|---|---|
| src | 只能是圖片,不能是xml定義的drawable |
| gravity | |
| antialias | 是否開啟抗鋸齒 |
| dither | 是否抖動 |
| filter | 對圖片進行濾波 |
| tileMode | repeat、mirror、clamp(邊緣拉伸)、disable |
| tint | 着色 |
| mipmap | 是否可以用mipmap ,api>=17 |
| tileModeX | api>=21 |
| tileModeY | api>=21 |
| tintMode | api>=21 |
實現方法,有代碼和xml方式:
XML方式
在res/drawable下定義bitmap drawable。
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@mipmap/cute" android:tileMode="mirror" android:dither="true" android:antialias="true"/>
- 1
- 2
- 3
- 4
- 5
代碼方式
Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.cute); BitmapDrawable bd = new BitmapDrawable(getResources(),b); bd.setAntiAlias(true); bd.setTileModeXY(Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); ivBitmapPic.setImageDrawable(bd);
- 1
- 2
- 3
- 4
- 5
NinePatchDrawable
.9圖片最大的特點是在拉伸不會失幀。.9圖片只能用於圖片拉伸的情況。
也是可以res/drawable中使用<nine-patch>標簽來定義一個NinePatchDrawable。不過都需要.9.png的圖片。Android提供了.9圖片的制作工具,在/tools目錄下。
PictureDrawable
- Picture類。
android.graphics.Picture。
不存儲實際的像素,僅僅記錄繪制的過程。 - PictureDrawable(Picture p)
使用PictureDrawable,很多手機顯示不出來。需要關閉對應的activity的硬件加速屬性。
android:hardwareAccelerated="false"
一般在代碼中實現:
Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.cute); Paint paint = new Paint(); paint.setTextSize(30); Picture p = new Picture(); Canvas c= p.beginRecording(b.getWidth(),b.getHeight()); c.drawBitmap(b,0,0,paint); c.drawText("PictureDrawable",20,50,paint); p.endRecording(); PictureDrawable drawable = new PictureDrawable(p); ivPicDrawable.setImageDrawable(drawable);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Color類型的Drawable
ColorDrawable和ColorFilter
ColorDrawable
在Android工程的res目錄下有兩個地方可以設置ColorDrawable,分別是drawable和values目錄,使用標簽來設置color。 在drawable目錄下設置color:
<?xml version="1.0" encoding="utf-8"?> <color xmlns:android="http://schemas.android.com/apk/res/android" android:color="#ff0000" />
- 1
- 2
- 3
在values目錄下設置color:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <drawable name="colorDrawable">#000000</drawable> </resources>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
ColorFilter
ColorFilter有3個子類。ImageView和ImageButton、Drawable以及Paint可以設置ColorFilter。
| 子類ColorFilter | 說明 |
|---|---|
| ColorMatrixColorFilter | 指定一個4*5的ColorFilter |
| LightingColorFilter | RGB顏色通道強度變換 |
| PorterDuffColorFilter | RGB色混合效果,有18種混合效果 |
- **ColorMatrix**
private void setArgb(int alpha,int red,int green,int blue){ ColorMatrix colorMatrix = new ColorMatrix(new float[]{ red,0,0,0,0, 0,green,0,0,0, 0,0,blue,0,0, 0,0,0,alpha,0 }); drawable.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); view.postInvalidate(); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- LightingColorFilter LightingColorFilter(int mul,int add)= (mul * 原色值 + add) % 255
//表示過濾了blue的顏色,並增強55 drawable.setColorFilter(new LightingColorFilter(0x0000ff,0x000055));
- 1
- 2
- PorterDuffColorFilter PorterDuffColorFilter(int srcColor,PorterDuff.Mode mode)
//mutate方法可以讓同一個drawable在不同的控件上進行展示不同的效果。
drawable.mutate().setColorFilter(new PorterDuffColorFilter(0x0000ff, PorterDuff.Mode.ADD));//18種效果。
- 1
- 2
GradientDrawable和Tint
GradientDrawable linearGradient = new GradientDrawable(); linearGradient.setGradientType(GradientDrawable.LINEAR_GRADIENT);// RADIAL_GRADIENT,SWEEP_GRADIENT //xml中只有startColor、centerColor和endColor,在代碼中可以設置任意多個color。 linearGradient.setColors(new int[]{0xff0000, 0xff0001, 0x000ff1, 0xff2310, 0x12ff00});//API 16 above linearGradient.setShape(GradientDrawable.RECTANGLE);//OVAL,LINE,RING view.setBackground(linearGradient); // API 16 above
- 1
- 2
- 3
- 4
- 5
- 6
Android5.0以后,引用了Tint的功能。
android:backgroundTint , android:tint及其對應的tintMode。ImageView有這兩個屬性,其它的只有backgound的tint。
管理多個Drawable
LayerDrawable、LevelListDrawable 和 TransitionDrawable 它們之間有些相似性,都是管理多個 Drawable 的展示,其中 TransitionDrawable 是 LayerDrawable 的子類只管理2個 Drawable。不過,從類繼承體系上分,LevelListDrawable 和 StateListDrawable 才是比較靠近的,效果也相似。
StateListDrawable
在res/drawable目錄下可以定義根據View的狀態(pressed,focus,checked等)的不同而顯示不同drawable的drawable。這種drawable在開發中經常會用到,比如按鈕點擊顯示按下去的背景。
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="300" android:exitFadeDuration="300"> <item android:drawable="@drawable/shape_selected" android:state_selected="true"/> <item android:drawable="@drawable/shape_selected" android:state_pressed="true"/> <item android:drawable="@drawable/shape_normal" /><!-- 務必將無狀態放在最后 --> </selector>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
注意:將正常狀態的drawable放到最后,不然會看不到狀態變化而導致的drawable變化。因為statelist drawbale是從上到下來搜索,如果有匹配的狀態,則顯示對應drawable。
LayerDrawable
LayerDrawable是一個多層的Drawable,可以對每一層的drawable進行控制。從而實現一些效果。它是這樣在drawable目錄下定義的:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/mv" android:left="20dp" android:top="20dp" android:id="@+id/l1"/> <item android:drawable="@mipmap/mv" android:left="40dp" android:top="40dp" android:id="@+id/l2"/> <item android:left="60dp" android:top="60dp" android:id="@+id/l3"> <shape > <gradient android:centerColor="@color/blue"></gradient> </shape> </item> </layer-list>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
可以為每一層drawable設置id,這樣可以控制每一層的drawable,從而達到一些特定的效果。比如下面是將最上層的drawable隱藏掉。
通過Drawable d1 = custLayerDrawable.findDrawableByLayerId(R.id.l1);找到某個id對應的Drawable,然后可以進行操作,比如隱藏:d1.setAlpha(0);
當然,也可以通過代碼來設置一個多層的drawable。例如:
DisplayMetrics dm = getResources().getDisplayMetrics(); Drawable [] ds = new Drawable[3]; ds[0] = getResources().getDrawable(R.mipmap.mv); ds[1] = getResources().getDrawable(R.mipmap.mv); ds[2] = getResources().getDrawable(R.mipmap.mv); LayerDrawable layerDrawable = new LayerDrawable(ds); layerDrawable.setLayerInset(0,0,0,(int)(20 * dm.density),(int)(20 * dm.density));//第一個參數表示索引。 layerDrawable.setLayerInset(1,0,0,(int)(40 * dm.density),(int)(40 * dm.density)); layerDrawable.setLayerInset(2,0,0,(int)(60 * dm.density),(int)(60 * dm.density)); imageViewLayer.setImageDrawable(layerDrawable);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
LevelListDrawable
LevelListDrawable根據level-list中的每一個draawable的level范圍來顯示對應的drawable。比如在drawable目錄中定義一個level-list:
<!-- 的每一個level-child表示一種不同的顏色,只在一定的level值區間顯示,方便演示。 --> <level-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/level_child" android:maxLevel="10" android:minLevel="0"/> <item android:drawable="@drawable/level_child1" android:maxLevel="20" android:minLevel="11"/> <item android:drawable="@drawable/level_child2" android:maxLevel="30" android:minLevel="21"/> <item android:drawable="@drawable/level_child3" android:maxLevel="40" android:minLevel="31"/> <item android:drawable="@drawable/level_child4" android:maxLevel="50" android:minLevel="41"/> </level-list>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
效果如圖,當拖動seekbar改變drawable的level值時,進入到不同的level區間,則會顯示不同的子drawable。 
TransitionDraeable
TransitionDraeable繼承LayerDrawable,但它只能有2個子drawable。切換drawable會產生漸變動畫,這時一個非常好的效果。同樣,先定義drawable文件:
<transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/level_child4" /> <item android:drawable="@drawable/level_child5" /> </transition>
- 1
- 2
- 3
- 4
然后在代碼中設置開始漸變,里面的參數表示動畫的時間:兩個方法,一個表示正向漸變,一個表示反向漸變。
transitionDrawable.startTransition(500); transitionDrawable.reverseTransition(500);
- 1
- 2
效果如下: 
容器類 Drawable
ClipDrawable、InsetDrawable、RotateDrawable和ScaleDrawable 都是 DrawableWrapper 的子類。它們都是容器類 Drawable,自生只能有一個子 Drawable,通過對子 Drawable 進行處理來實現 clip、inset、rotate、scale 的效果
ClipDrawable
使用<clip>標簽定義ClipDrawable,在res/drawable目錄中。
<!-- 水平方向裁剪、裁剪時從右到左、對gradient_progress進行裁剪--> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="horizontal" android:gravity="left" android:drawable="@drawable/gradient_progress_h"> </clip>
- 1
- 2
- 3
- 4
- 5
- 6
<!-- 圖片四周擴散和四周聚攏--> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="horizontal|vertical" android:gravity="center" android:drawable="@mipmap/mv"> </clip>
- 1
- 2
- 3
- 4
- 5
- 6
通過在代碼中設置Drawable的Level來控制裁剪效果。容器類Drawable都是通過setLevel(int level)來控制的,level值的范圍是[0,10000]。
imageView.getDrawable().setLevel(10000);
- 1
效果圖: 
InsetDrawable
InsetDrawable主要是為設置backgroud背景的控件的drawable設置邊距,類似padding。設置方式也是在res/drawable目錄下,使用<inset>標簽,里面放一個drawable,然后設置四個邊距。
<inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/inset_shape" android:insetBottom="20dp" android:insetLeft="20dp" android:insetRight="20dp" android:insetTop="20dp"> </inset>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
RotateDrawable
RotateDrawable很容易實現旋轉的效果。比如指針轉盤。同樣是在res/drawable目錄下,使用<rotate>標簽來設定一個RotateDrawabl。
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/mv" android:fromDegrees="0" android:toDegrees="180" android:pivotX="50%"<!-- %p表示在父控件中的百分比 --> android:pivotY="50%"<!-- %p表示在父控件中的百分比 --> android:visible="true"> </rotate>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
上面定義了一個圖片,從0°-180°,以自己的中心點為中心旋轉180。 
ScaleDrawable
ScaleDrawable很容易實現縮放的效果。設置方式和上面的drawable一樣。如:
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/mv" android:useIntrinsicSizeAsMinimum="false" android:scaleWidth="50%"<!-- 寬度縮放比例 --> android:scaleHeight="50%"<!-- 高度縮放比例 --> android:scaleGravity="right|top"><!-- 縮放后的位置 --> </scale>
- 1
- 2
- 3
- 4
- 5
- 6
- 7

矢量圖VectorDrawable
在 Android5.0(API Level 21)中引入了 VectorDrawable 和 AnimatedVectorDrawable,矢量圖不會因為圖像放大而失真,而且占用內存小。所以學會矢量圖並用好它,將對開發 APP 非常有用。VectorDrawable只支持部分的SVG規范。一般去找成型的SVG圖片。
VectorDrawable
矢量圖中保存的只是圖像繪制的方法:
大寫代表后面的參數是絕對坐標,小寫代表相對坐標。
| 方法 | 說明 |
|---|---|
| M | moveTo繪制點。 |
| L | lineTo畫直線 |
| Z | close開始點-結束點閉合 |
| C | cubic bezier三次貝塞爾曲線 |
| Q | quatratic bezier二次貝塞爾曲線 |
| A | 圓弧rx ry x-rotation large-arc-flag sweep-flag xy |

<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="60dp" android:height="60dp" android:viewportHeight="600" android:viewportWidth="600"> <group android:name="group" android:pivotX="300.0" android:pivotY="300.0" android:rotation="0.0"> <path android:name="v" android:fillColor="@android:color/black" android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /><!-- M到300,70,然后l到0,-70 --> </group> </vector>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
AnimatedVector
屬於屬性動畫。
此篇文章是學習極客學院hexter老師的做的筆記。
