前言
不管是在手游开发过程中还是自定义组件开发过程中,都需要绘图相应的支持。Android应用常常需要在运行时动态地生成图片,而且可以随用户的动作发生相应的改变,这就需要需要借助于绘图技术的支持了。
绘图基础
绘图基础包括两个部分,分别是Paint和Canvas,也就是我们常常所说的画笔和画布,为什么这样去比喻呢?这可以联想到小时候上美术课,我们在上课之前一般都要提前准备一个画本和一套画笔吧!画本是很多张画纸组成,也就是我要说的画布,我们在画画时,仅仅需要一张画布就可以。画笔就不用多说了嘛,就是我们小时用得最多的彩笔。
那么画笔和画布都准备好了,谁来做画呢?当然是我们程序员自己啊,你就把自己理解成一个小小画家就好啦,也是和我们小时候画画一样一手拿画笔一手拿画纸(画布)。当然画家有伟大的也有普通,伟大的画家可以理解为CSDN,GitHub等上面的一些技术大牛,可以“画”出效果出众的UI(自定义组件)。当然也有普通的画家,就像现在的自己一样仅仅只能模仿一下市场上出现的UI,不过谁不想成为伟大的画家呢,这几天学习了一下安卓的绘画知识和大家分享一下,之前也看过别人写的关于Android绘画这方面的博客,但是个人感觉比喻的不是蛮准确,有的人把canvas比作画家,还有什么画笔和画布组合比喻成画家,然而画家不就是我们自己么,好了不多说了,开始正文把~
在啰嗦一点点吧!现在本人毕竟能力有限,在概念上一般会先引用官方文档,之前自己查资料也是看别人的博客被害惨了,现在在概念上尽量先引用官网的,理解如有瑕疵,望其斧正,鄙人不胜感激~
Paint
java.lang.Object
↳ android.graphics.Paint
说明
The Paint class holds the style and color information about how to draw geometries, text and bitmaps.
Paint是一个持有样式和颜色信息的类,是用来如何操作几何图形,文本和bitmap对象的
对于画笔是持有样式和颜色信息的一个类,其实很好理解。在现实生活中,一些画家在写生的时,一般会把画质架在一块木制加班上,然后旁边放一个颜料盘,里面放着需要的各种颜色,而画家仅拿一只画笔,需要什么颜色的时候,就去蘸颜料盘里相应的颜色。
但是程序毕竟和现实世界还是有些不一样的,在现实世界中,画笔的样式,和画笔的颜色都是一个单独的个体而存在,在官方提供的API文档描述中,样式和画笔颜色信息都在Paint类中来描述。所以在使用样式的时候尽量这样去使用Paint.Style.xxx因为在Android中组件的样式各种各样,尽量各自使用时,在自己的范围内行使,避免不必要的混淆。
Style
style | value | describe |
---|---|---|
Paint.Style | FILL | Geometry and text drawn with this style will be filled, ignoring all stroke-related settings in the paint. |
Paint.Style | FILL_AND_STROKE | Geometry and text drawn with this style will be both filled and stroked at the same time, respecting the stroke-related fields on the paint. |
Paint.Style | STROKE | Geometry and text drawn with this style will be stroked, respecting the stroke-related fields on the paint. |
- 第一条意思是说,几何图性和文本的绘制将使用FILL(填充)样式来绘制,而忽略所有STROKE (描边)样式
- 第二条意思是说,几何图性和文本的绘制将使用FILL(填充)和STROKE (描边)样式来绘制。
- 第三条意思是说,几何图性和文本的绘制将使用STROKE (描边)样式来绘制,而忽略所有FILL(填充)样式。
retValue | method | describe |
---|---|---|
void | setStyle(Paint.Style style) | Set the paint’s style, used for controlling how primitives’ geometries are interpreted (except for drawBitmap, which always assumes Fill). |
样式使用
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
颜色就不用多说了,直接使用就好
paint.setColor(Color.BLACK);
看看paint的常用方法吧
retValue | method | describe |
---|---|---|
float | measureText(String text) | Return the width of the text. |
float | measureText(CharSequence text, int start, int end) | Return the width of the text. |
float | measureText(String text, int start, int end) | Return the width of the text. |
float | measureText(char[] text, int index, int count) | Return the width of the text. |
void | reset() | Restores the paint to its default settings.重置paint的默认设置 |
void | set(Paint src) | Copy the fields from src into this paint. |
void | setARGB(int a, int r, int g, int b) | Helper to setColor(), that takes a,r,g,b and constructs the color int |
void | setAlpha(int a) | Helper to setColor(), that only assigns the color’s alpha value, leaving its r,g,b values unchanged. |
void | setAntiAlias(boolean aa) | Helper for setFlags(), setting or clearing the ANTI_ALIAS_FLAG bit AntiAliasing smooths out the edges of what is being drawn, but is has no impact on the interior of the shape.设置paint抗锯齿 |
void | setColor(int color) | Set the paint’s color. |
void | setDither(boolean dither) | Helper for setFlags(), setting or clearing the DITHER_FLAG bit Dithering affects how colors that are higher precision than the device are down-sampled.防抖动设置 |
void | setFlags(int flags) | Set the paint’s flags. |
void | setFontFeatureSettings(String settings) | Set font feature settings. |
void | setHinting(int mode) | Set the paint’s hinting mode. |
void | setLetterSpacing(float letterSpacing) | Set the paint’s letter-spacing for text. |
void | setLinearText(boolean linearText) | Helper for setFlags(), setting or clearing the LINEAR_TEXT_FLAG bit |
MaskFilter | setMaskFilter(MaskFilter maskfilter) | Set or clear the maskfilter object. |
PathEffect | setPathEffect(PathEffect effect) | Set or clear the patheffect object. |
Shader | setShader(Shader shader) | Set or clear the shader object. |
void | setShadowLayer(float radius, float dx, float dy, int shadowColor) | This draws a shadow layer below the main layer, with the specified offset and color, and blur radius. |
void | setStrokeWidth(float width) | Set the width for stroking.设置描边”笔尖”的粗细 |
void | setStyle(Paint.Style style) | Set the paint’s style, used or controlling how primitives’ geometries are interpreted (except for drawBitmap, which always assumes Fill). |
Canvas
retValue | method | describe |
---|---|---|
boolean | clipPath(Path path) | 剪裁一个指定区域 |
boolean | clipPath(Path path, Region.Op op) | 剪裁一个指定区域 |
void | drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) | 绘制弧形 |
void | drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) | 在指定源位图中”挖取”一块 |
void | drawBitmap(Bitmap bitmap, float left, float top, Paint paint) | 在指点绘制一个位图 |
void | drawCircle(float cx, float cy, float radius, Paint paint) | 在指点绘制一个圆形 |
void | drawColor(int color) | 填充画布背景颜色 |
void | drawLine(float startX, float startY, float stopX, float stopY, Paint paint) | 绘制一条线 |
void | drawLines(float[] pts, Paint paint) | 绘制多条线 |
void | drawOval(float left, float top, float right, float bottom, Paint paint) | 绘制一个椭圆 |
void | drawOval(RectF oval, Paint paint) | 绘制一个椭圆 |
void | drawPath(Path path, Paint paint) | 沿着指定的路径绘制任意形状 |
void | drawPicture(Picture picture, RectF dst) | Draw the picture, stretched(拉升) to fit into the dst rectangle. |
void | drawPoint(float x, float y, Paint paint) | 绘制点 |
void | drawPoints(float[] pts, int offset, int count, Paint paint) | 绘制多个点 |
void | drawRect(float left, float top, float right, float bottom, Paint paint) | 绘制矩形 |
void | drawRect(RectF rect, Paint paint) | 绘制矩形 |
void | drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) | 再指定点绘制圆角矩形 |
void | drawRoundRect(RectF rect, float rx, float ry, Paint paint) | 再指定点绘制圆角矩形 |
void | drawText(String text, float x, float y, Paint paint) | 再指定点绘制文本 |
void | drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) | 沿着路径绘制文本 |
好了写了这么多,开始得连下手了
ViewActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
}
activity_view.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"
android:orientation="vertical" >
<com.example.android_canvas_001.MyViewNew
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
MyView.java
public class MyViewNew extends View {
public MyViewNew(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
// 去锯齿
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE); // 描边
paint.setStrokeWidth(3);
int width = 10;
// 绘制圆形
canvas.drawCircle(width + 30, 40, 30, paint);
// 绘制正方形
canvas.drawRect(new Rect(width, 90, 80, 180), paint);
// 绘制矩形
canvas.drawRect(new Rect(width, 200, 140, 240), paint);
// 绘制圆角矩形
canvas.drawRoundRect(new RectF(width, 260, 80, 330), 10, 10, paint);
// 绘制椭圆
canvas.drawOval(new RectF(width, 350, 210, 400), paint);
// 绘制一个三角形
Path p = new Path();
p.moveTo(width + 80, 420);
p.lineTo(width, 500);
p.lineTo(width + 160, 500);
p.close();
canvas.drawPath(p, paint);
// 绘制倒三角
p = new Path();
p.moveTo(width, 520);
p.lineTo(width + 80, 520);
p.lineTo(width + 40, 560);
p.close();
canvas.drawPath(p, paint);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
canvas.drawLine(250, 0, 250, 600, paint);
// 设置填充模式
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setColor(Color.RED);
width = 270;
// 绘制圆形
canvas.drawCircle(width + 30, 40, 30, paint);
// 绘制正方形
canvas.drawRect(new Rect(width, 90, width+80, 180), paint);
// 绘制矩形
canvas.drawRect(new Rect(width, 200, width+140, 240), paint);
// 绘制圆角矩形
canvas.drawRoundRect(new RectF(width, 260, width+80, 330), 10, 10, paint);
// 绘制椭圆
canvas.drawOval(new RectF(width, 350, width+210, 400), paint);
// 绘制一个三角形
p = new Path();
p.moveTo(width + 80, 420);
p.lineTo(width, 500);
p.lineTo(width + 160, 500);
p.close();
canvas.drawPath(p, paint);
// 绘制倒三角
p = new Path();
p.moveTo(width, 520);
p.lineTo(width + 80, 520);
p.lineTo(width + 40, 560);
p.close();
canvas.drawPath(p, paint);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
canvas.drawLine(0, 600, 600, 600, paint);
paint.setTextSize(30.0f);
canvas.drawText("this is a text~", 20, 640, paint);
}
}
效果如下: