Overview
ShapeDrawable 根据原始的形状来绘制图形,如矩形,圆形,线条等,可以是一个纯色的色块,也可以渐变的效果。当没有设置具体的图形时,默认为矩形。
创建和使用
ShapeDrawable可以使用<shape>
标签在xml文件中定义,但是与之前介绍的几种Drawable不同,<shape>
标签指向GradientDrawable的指针,也就是说编译的类型是GradientDrawable。
(COMPILED RESOURCE DATATYPE: Resource pointer to a GradientDrawable.)
语法:
<?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:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="integer"
android:centerY="integer"
android:centerColor="integer"
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>
- 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
- 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
元素:
<shap>
The shape drawable. 必须是根元素。
-
Android:shape 表示图形的形状,可以定义下面四种类型的形状:
-
<corners>
角度 ( 只适用于 shape )表示shape图形四个角的圆角程度,每个圆角半径值都必须大于1,否侧就没有圆角。
- android:radius 为四个角同时设定相同的角度,优先级低,会被下面几个覆盖。
- android:topLeftRadius 左上角的角度
- android:topRightRadius 右上角的角度
- android:bottomLeftRadius 左下角的角度
- android:bottomRightRadius 右下角的角度
<gradient>
渐变效果
- android:angle 渐变的角度,默认是0,其值必须是45的整数倍。0表示从左边到右,90表示从上到下。具体效果随着角度的调整而产生变化,角度影响渐变方向。
- android:centerX 渐变中心的横坐标点
- android:centerY 渐变中心的纵坐标点
- android:centerColor 渐变色的中间色
- android:endColor 渐变色的结束色
- android:gradientRadius 渐变的半径(仅当 android:type 为radio时有效)
- android:startColor 渐变色的起始色
- android:type 渐变的类型
- linear 线性渐变 (默认值)
- radial 径向渐变
- sweep 扫描线渐变
- android:useLevel 一般为false,当Drawable作为StateListDrawable时有效。
-
<padding>
内边距
android:top\bottom\left\right 分别设置上下左右的内边距。
-
<size>
shape大小
- android:height 指定shape高
- android:width 指定shape宽
严格来说shape没有宽高,但是我们指定size就有了所谓的宽高。当shape作为View 的背景时,shape还是会被拉伸的,所以这个宽高并不是指定多少就固定了shape大小(对于Drawable都是没有绝对的宽高的)。
-
<solid>
纯色填充 (与gradient互斥,纯色或者渐变只能取一个)
-
<stroke>
描边
- android:width 描边的宽度,越大则shape的边缘线越粗
- android:color 描边的颜色
- android:dashGap 虚线的空隙的间隔
- android:dashWidth 虚线的宽度
注:如果 android:dashWidth 和 android:dashGap 两者有任意一个为0,那么虚线效果就无法显示。
上面说了<shape>
编译后的类型是GradientDrawable,如果要定义ShapeDrawable目前好像只能在代码中创建。我们来看一个例子:
原文链接:http://www.java2s.com/Code/Android/2D-Graphics/ShapeDrawableDemo.htm
public class Test extends GraphicsActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private ShapeDrawable[] mDrawables;
private static Shader makeSweep() {
return new SweepGradient(150, 25, new int[] { 0xFFFF0000,
0xFF00FF00, 0xFF0000FF, 0xFFFF0000 }, null);
}
private static Shader makeLinear() {
return new LinearGradient(0, 0, 50, 50, new int[] { 0xFFFF0000,
0xFF00FF00, 0xFF0000FF }, null, Shader.TileMode.MIRROR);
}
private static Shader makeTiling() {
int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0 };
Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
Bitmap.Config.ARGB_8888);
return new BitmapShader(bm, Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
}
private static class MyShapeDrawable extends ShapeDrawable {
private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public MyShapeDrawable(Shape s) {
super(s);
mStrokePaint.setStyle(Paint.Style.STROKE);
}
public Paint getStrokePaint() {
return mStrokePaint;
}
@Override
protected void onDraw(Shape s, Canvas c, Paint p) {
s.draw(c, p);
s.draw(c, mStrokePaint);
}
}
public SampleView(Context context) {
super(context);
setFocusable(true);
float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
RectF inset = new RectF(6, 6, 6, 6);
float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
Path path = new Path();
path.moveTo(50, 0);
path.lineTo(0, 50);
path.lineTo(50, 100);
path.lineTo(100, 50);
path.close();
mDrawables = new ShapeDrawable[7];
mDrawables[0] = new ShapeDrawable(new RectShape());
mDrawables[1] = new ShapeDrawable(new OvalShape());
mDrawables[2] = new ShapeDrawable(new RoundRectShape(outerR, null,
null));
mDrawables[3] = new ShapeDrawable(new RoundRectShape(outerR, inset,
null));
mDrawables[4] = new ShapeDrawable(new RoundRectShape(outerR, inset,
innerR));
mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
mDrawables[0].getPaint().setColor(0xFFFF0000);
mDrawables[1].getPaint().setColor(0xFF00FF00);
mDrawables[2].getPaint().setColor(0xFF0000FF);
mDrawables[3].getPaint().setShader(makeSweep());
mDrawables[4].getPaint().setShader(makeLinear());
mDrawables[5].getPaint().setShader(makeTiling());
mDrawables[6].getPaint().setColor(0x88FF8844);
PathEffect pe = new DiscretePathEffect(10, 4);
PathEffect pe2 = new CornerPathEffect(4);
mDrawables[3].getPaint().setPathEffect(
new ComposePathEffect(pe2, pe));
MyShapeDrawable 马上到! = (MyShapeDrawable) mDrawables[6];
马上到!.getStrokePaint().setStrokeWidth(4);
}
@Override
protected void onDraw(Canvas canvas) {
int x = 10;
int y = 10;
int width = 300;
int height = 50;
for (Drawable dr : mDrawables) {
dr.setBounds(x, y, x + width, y + height);
dr.draw(canvas);
y += height + 5;
}
}
}
}
- 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
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 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
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
可见使用代码创建ShapeDrawable还是比较复杂的,除非有特别的自定义要求,否则我们一般直接使用<shape>
在xml定义。
原文链接:https://liuzhichao.com/2016/android-shapedrawable.html