Android绘图方法主要有两个步骤:
(1)实现一个继承于View组件的类,并重写它的onDraw(Canavas canvas)方法;
(2)显示定义的View子类,有两种方法:
a.使用一个Activity来显示View子类,即 setContentView(new MyView(this, null));
b.在Acitviy的布局文件中增加"包名.View子类"元素,Activiyty通过setContentView方法来使用该布局文件。
下面我们来学习下Android绘制图形的三个最重要的API工具。
一、Android绘图三大API1.Canvas类
(1)功能:Canvas代表了"依附"于指定View的画布,通过Canvas类的成员方法能够实现绘制各种图形。绘制一个图形由四部分组成:Bitmap、Canvas、Path/Rect/text等、Paint,其中Bitmap为绘制图形存放的像素位图,Canvas用于提供绘制图像方法、Paint为画笔、Path/Rect/text等分别为绘制图形的(轨迹/矩形/文本)。
(2)构造方法Canvas()
:构造空的canvas对象Canvas(Bitmap bitmap) :构造一个Canvas对象,并指定其bitmap
(3)常用方法
boolean | clipRegion(Region region):剪切指定区域 |
void | drawBitmap(Bitmap bitmap,float left, float top, Paint paint):在指定点(x,y)使用指定的画笔paint绘制位图 |
void | drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint):在指定点(x,y)绘制从源位图中"挖取"的一块 |
void | drawCircle(floatcx, float cy, float radius, Paint paint):绘制原点为(cx,cy),半径为radius的圆 |
void | drawLine(floatstartX, float startY, float stopX, float stopY, Paint paint):绘制一条起点为(startX,startY),终点为(stopX,stopY)直线 |
void | drawLines(float[]pts, int offset, int count, Paint paint):绘制多条直线,其中pts为一个浮点型数组提供绘制一条直接所需的数据(4个/条),count为绘制直线的条数 |
void | drawOval(RectF oval, Paint paint):绘制一个椭圆,oval为绘制椭圆的矩形边界 |
void | drawPath(Path path, Paint paint):沿着路径path绘制图形 |
void | drawPoint(floatx, float y, Paint paint):绘制一个点(x,y) |
void | drawPoints(float[]pts, int offset, int count, Paint paint):绘制pts数组中的多个点(2个值/点) |
void | drawRect(floatleft, float top, float right, float bottom, Paint paint):绘制一个矩形,其参数为距离屏幕边界的距离(边界为0) |
void | drawRoundRect(RectF rect,float rx, float ry, Paint paint):使用指定的画笔绘制圆角矩形,其中rect为矩形边界、rx/ry分别为以矩形顶点为(0,0)相对位置圆的x半径、y半径 |
void | drawText(String text,float x, float y, Paint paint):以(x,y)为原点,使用指定画笔绘制文本 |
void | drawTextOnPath(String text, Path path,float x, float y, Paint paint):以(x,y)为原点,使用指定的画笔沿着指定路径绘制文本 |
int | getHeight():返回当前图层的高度 |
int | getWidth():返回当前绘图层的宽度 |
void | rotate(floatdegrees):对Canvas执行旋转变换; |
void | setBitmap(Bitmap bitmap):指定Canvas(画布)的位图Bitmap |
void | translate(floatdx, float dy):相对于当前位置移动Canvas。向右移动dx距离(dx为负数即向左移动);向下移动dy距离(dy为负数即向上移动) |
void | skew(float sx,float sy):对Canvas执行倾斜变换 |
2.Paint类
void | reset():恢复画笔到默认配置 |
void | setARGB(inta, int r, int g, int b):设置画笔透明度和颜色,其参数分别代表透明度、红色、绿色、蓝色 |
void | setAlpha(inta):设置画笔的透明度 |
void | setAntiAlias(booleanaa):设置是否抗锯齿 |
void | setColor(intcolor):设置画笔的颜色 |
void | setFlags(intflags):设置画笔的flags(HINTING_OFF、HINTING_ON等) |
void | setHinting(intmode):设置画笔的提示模式 |
PathEffect | setPathEffect(PathEffect effect):设置绘制路径时的路径效果(ComposePathEffect,CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect) |
Rasterizer | setRasterizer(Rasterizer rasterizer) |
Shader | setShader(Shader shader):设置画笔的填充效果(BitmapShader,ComposeShader, LinearGradient, RadialGradient, SweepGradient) |
void | setShadowLayer(floatradius, float dx, float dy, int color):设置阴影效果 |
void | setStrokeJoin(Paint.Join join):设置画笔转弯处的连接风格(BEVEL-直线、MITER-锐角、ROUND-圆弧 ) |
void | setStrokeWidth(floatwidth):设置画笔宽度 |
void | setStyle(Paint.Style style):设置Paint的填充风格(FILL-、FILL_AND_STROKE、STROKE ) |
void | setTextAlign(Paint.Align align):设置绘制文本时的文字对齐方式(CENTER-居中、LEFT-靠左、RIGHT -靠右:以(x,y)为中心) |
void | setTextSize(floattextSize):设置绘制文本的文字大小 |
boolean | isEmpty():判定Path对象是否为空(即不包含直线或曲线),如果为空返回true |
void | lineTo(floatx, float y):增加一条从上一点到当前点(x,y)的直线 |
void | moveTo(floatx, float y):设置下一个轮廓的开始点(x,y) |
void | rLineTo(floatdx, float dy):以坐标为参照增加一条从上一点到当前点(x,y)的直线 |
void | rMoveTo(floatdx, float dy):以坐标为参照设置下一个轮廓的开始点(x,y) |
void | reset():删除Path对象的所有直线和曲线 |
void | set(Path src):将当前Path对象的内容替换为对象src所包含的内容 |
void | setFillType(Path.FillType ft):设置路径的填充类型 |
void | setLastPoint(floatdx, float dy):设置路径的最后一个点的坐标为(x,y) |
void | transform(Matrix matrix):通过matrix转换该路径中的点 |
void |
close() :释放资源 |
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.canvaspaint; public class MyView extends View { // 1.构造方法 public MyView(Context context, AttributeSet set) { super(context, set); } // 2.重写onDraw方法进行绘图 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // a.初始化画布、画笔 canvas.drawColor(Color.WHITE); // 设置画布绘制成白色 Paint paint = new Paint(); paint.setAntiAlias(true); // 去锯齿 paint.setColor(Color.BLUE); // 设置画笔为蓝色 paint.setStyle(Paint.Style.STROKE); // 设置画笔的填充风格 /*------------------------无填充风格绘制----------------------------*/ // b.绘制圆形 canvas.drawCircle(30, 30, 30, paint); // c.绘制正方形 canvas.drawRect(10, 30, 50, 50, paint); // d.绘制矩形 canvas.drawRect(30, 30, 200, 200, paint); // e.绘制圆角矩形 RectF re1 = new RectF(30,30, 200, 200); canvas.drawRoundRect(re1, 30,30, paint); // f.绘制椭圆 RectF re11 = new RectF(30,30,100, 80); canvas.drawOval(re11, paint); //g.定义一个Path对象,封闭成一个三角形并根据Path对象绘制 Path path1 = new Path(); path1.moveTo(10, 340); path1.lineTo(70, 340); path1.lineTo(40, 290); path1.close(); canvas.drawPath(path1, paint); // h.根据Path绘制五角形 Path path2 = new Path(); path2.moveTo(26, 360); path2.lineTo(54, 360); path2.lineTo(70, 392); path2.lineTo(40, 420); path2.lineTo(10, 392); path2.close(); canvas.drawPath(path2, paint); /*------------------------设置填充风格后绘制----------------------------*/ paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); // b.绘制圆形 canvas.drawCircle(120, 40, 30, paint); // c.绘制正方形 canvas.drawRect(90, 80, 150, 140, paint); // d.绘制矩形 canvas.drawRect(90, 150, 150, 190, paint); // e.绘制圆角矩形 RectF re2 = new RectF(90, 200, 70, 230); canvas.drawRoundRect(re2, 15, 15, paint); // f.绘制椭圆 RectF re22 = new RectF(90, 240, 150, 270); canvas.drawOval(re22, paint); // g.定义一个Path对象,封闭成一个三角形并根据Path对象绘制 Path path3 = new Path(); path3.moveTo(90, 340); path3.lineTo(150, 340); path3.lineTo(120, 290); path3.close(); canvas.drawPath(path3, paint); // h.根据Path绘制五角形 Path path4 = new Path(); path4.moveTo(106, 360); path4.lineTo(134, 360); path4.lineTo(150, 392); path4.lineTo(120, 420); path4.lineTo(90, 392); path4.close(); canvas.drawPath(path4, paint); /*------------------------设置渐变器后绘制----------------------------*/ Shader mShader = new LinearGradient(0,0,40,60,new int[] {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},null,Shader.TileMode.REPEAT); paint.setShader(mShader); paint.setShadowLayer(45, 10, 10, Color.GRAY); //b.绘制圆形 canvas.drawCircle(200,40,30, paint); //c.绘制正方形 canvas.drawRect(170,80,230,140,paint); //d.绘制矩形 canvas.drawRect(170, 150, 230, 190, paint); //e.绘制圆角矩形 RectF re3= new RectF(170,200,230,230); canvas.drawRoundRect(re3, 15, 15, paint); //f.绘制椭圆 RectF re33 = new RectF(170,240,230,270); canvas.drawOval(re33, paint); //g.定义一个Path对象,封闭成一个三角形并根据Path对象绘制 Path path5 = new Path(); path5.moveTo(170, 340); path5.lineTo(230, 340); path5.lineTo(200, 290); path5.close(); canvas.drawPath(path5, paint); //h.根据Path绘制五角形 Path path6 = new Path(); path6.moveTo(186, 360); path6.lineTo(241, 360); path6.lineTo(230, 392); path6.lineTo(200, 420); path6.lineTo(170, 392); path6.close(); canvas.drawPath(path6, paint); /*---------------设置字符大小后绘制---------------*/ paint.setTextSize(30); paint.setShader(null); // //绘制7个字符串 canvas.drawText(getResources().getString(R.string.circle), 30, 30, paint); canvas.drawText(getResources().getString(R.string.square), 240, 120, paint); canvas.drawText(getResources().getString(R.string.rect), 240, 175, paint); canvas.drawText(getResources().getString(R.string.round_rect), 230, 220, paint); canvas.drawText(getResources().getString(R.string.oval), 240, 260, paint); canvas.drawText(getResources().getString(R.string.triangle), 240, 325, paint); canvas.drawText(getResources().getString(R.string.pentagon), 240, 390, paint); } }</span></span>
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.canvaspaint; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class CanvasTest extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this, null)); } }</span></span>效果演示:
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.android_path; public class PathTest extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } /*-----------------------构造方法---------------------------*/ class MyView extends View { float phase; PathEffect[] effects = new PathEffect[7]; int[] colors; private Paint paint; Path path; public MyView(Context context) { super(context); //1.初始化画笔Paint paint = new Paint(); //实例化一个(画笔)Paint对象 paint.setStyle(Paint.Style.STROKE); //设置Paint的填充风格 paint.setStrokeWidth(4); //2.创建并初始化Path path = new Path(); path.moveTo(0, 0); for(int i=1;i<=15;i++) { //生成15个点,随机生成它们的Y坐标,并将它们生成一条Path path.lineTo(i*20, (float)Math.random()*60); } //3.初始化7个颜色 colors = new int[] {Color.BLACK,Color.RED,Color.BLUE,Color.GRAY,Color.GREEN,Color.MAGENTA,Color.YELLOW}; } /*-----------------------绘图---------------------------*/ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); //将画布背景填充成白色 //4.初始化7种路径效果 effects[0]=null; //a.不使用路径效果 effects[1] = new CornerPathEffect(10); //b.初始化CornerPathEffect effects[2] = new DiscretePathEffect(3.0f,5.0f); //c.初始化DiscretePathEffect effects[3] = new DashPathEffect(new float[] {20,10,5,10}, phase); //d.初始化DashPathEffect Path p = new Path(); p.addRect(0, 0, 8, 8, Path.Direction.CCW); effects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE); //e.初始化PathDashPathEffect effects[5] = new ComposePathEffect(effects[2],effects[3]); //f.初始化ComposePathEffect effects[6] = new SumPathEffect(effects[4], effects[3]); //g.初始化SumPathEffect //5.将画布移动到(8,8)处开始绘制,依次使用7中不同路径效果、7中不同的颜色来绘制路径 canvas.translate(8, 8); for(int i=0;i<effects.length;i++) { paint.setPathEffect(effects[i]); paint.setColor(colors[i]); canvas.drawPath(path, paint); canvas.translate(0, 60); } //6.改变phase值,形成动画效果 phase +=1; invalidate(); } } }</span></span>
<span style="font-family:Times New Roman;"><span style="font-size:18px;">package com.example.path; /*沿着Path绘制文本*/ public class PathText extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new ViewText(this)); } class ViewText extends View { final String DRAW_STR = "何以笙箫默"; Path[] paths = new Path[3]; Paint paint; /*----------------------构造方法--------------------------*/ public ViewText(Context context) { super(context); paths[0] = new Path(); paths[0] .moveTo(0, 0); //第一条路径:自动生成7个点连成一条线 for(int i=1;i<=7;i++) { paths[0].lineTo(i*30, (float)Math.random()*30); } //第二条路径:为一个椭圆(200,120) paths[1] = new Path(); RectF rectF = new RectF(0,0,200,120); paths[1].addOval(rectF, Path.Direction.CCW); //第三条路径:为一条圆弧 paths[2] = new Path(); paths[2].addArc(rectF, 60, 180); //2.初始化画笔 paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.RED); paint.setStrokeWidth(1); } /*-------------------------绘图---------------------------------*/ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); //设置画布背景为白色 canvas.translate(40, 40); //a.设置从右边开始绘制(右对齐) paint.setTextAlign(Paint.Align.RIGHT); paint.setTextSize(20); //b.绘制第一条路径 paint.setStyle(Paint.Style.STROKE); //绘制路径 canvas.drawPath(paths[0],paint); paint.setStyle(Paint.Style.FILL);//沿着路径绘制一段文本 canvas.drawTextOnPath(DRAW_STR, paths[0], -8, 20, paint); //对Canvas进行坐标变换,画布下移120 canvas.translate(0, 60); //c.绘制第二条路径 paint.setStyle(Paint.Style.STROKE); //绘制路径 canvas.drawPath(paths[1], paint); paint.setStyle(Paint.Style.FILL); //沿着路径绘制一段文本 canvas.drawTextOnPath(DRAW_STR, paths[1], -20, 20, paint); //对Canvas进行坐标变换,画布下移120 canvas.translate(0, 120); //d.绘制第三条路径 paint.setStyle(Paint.Style.STROKE); //绘制路径 canvas.drawPath(paths[2], paint); paint.setStyle(Paint.Style.FILL); //沿着路径绘制一段文本 canvas.drawTextOnPath(DRAW_STR, paths[2], -10, 20, paint); } } }</span></span>
效果演示:
绘制文本
普通水平绘制drawText
这个比较简单,但是需要注意绘制text绘制精确位置使用FontMetrics
,主要包含四个参数:
ascent = ascent线的y坐标 - baseline线的y坐标;
descent = descent线的y坐标 - baseline线的y坐标;
top = top线的y坐标 - baseline线的y坐标;
bottom = bottom线的y坐标 - baseline线的y坐标;
指定每个文字位置
void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
void drawPosText (String text, float[] pos, Paint paint)
参数说明
char[] text:要绘制的文字数组
int index::第一个要绘制的文字的索引
int count:要绘制的文字的个数,用来算最后一个文字的位置,从第一个绘制的文字开始算起
float[] pos:每个字体的位置,同样两两一组,如{x1,y1,x2,y2,x3,y3……}
float []pos=new float[]{80,100,
100,200,
120,300,
140,400};
canvas.drawPosText("1234", pos, paint);
··
沿路径绘制
void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
参数说明:
float hOffset : 与路径起始点的水平偏移距离
float vOffset : 与路径中心的垂直偏移量
String string = "测试文字偏移的参数";
Path circlePath = new Path();
circlePath.addCircle(220, 200, 100, Path.Direction.CCW);
canvas.drawPath(circlePath, paint_red);//绘制出路径原形
Path circlePath2 = new Path();
circlePath2.addCircle(550, 200, 100, Path.Direction.CCW);
canvas.drawPath(circlePath2, paint_red);//绘制出路径原形
paint_green.setTextSize(30);
//hoffset、voffset参数值全部设为0,看原始状态是怎样的
canvas.drawTextOnPath(string, circlePath, 0, 0, paint_green);
//第二个路径,改变hoffset、voffset参数值
canvas.drawTextOnPath(string, circlePath2, 80, 30, paint_green);
http://www.jianshu.com/p/56048ce85946
原文:http://blog.csdn.net/xiabing082/article/details/54616350