本文主要是介绍Android Canvas 和Paint的用法 转自http://blog.csdn.net/u010947098/article/details/44574171,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
首先,介绍的是Canvas的基本方法
方法签名 | 简要说明 |
---|---|
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) | 绘制弧 |
drawBitmap(Bitmap bitmap, Rect src, Rect dst,Paint paint) | 在指定点绘制从源位图中"挖取"的一块 |
drawBitmap(Bitmap bitmap, float left, flost top, Paint paint) | 在指定点绘制位图 |
drawCircle(float cx, float cy, float radius, Paint paint) | 在指定点绘制一个圆形 |
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) | 绘制一条线 |
drawLines(float[] pts, int offset, int count, Paint paint) | 绘制多条线 |
drawOval(RectF oval, Paint paint) | 绘制椭圆 |
drawPath(Path path, Paint paint) | 沿着指定Path绘制任意形状 |
drawPoint(float x, float y, Paint paint) | 绘制一个点 |
drawPoints(float[] pts, int offset, int count, Paint paint) | 绘制多个点 |
drawRect(float left, float top, float right, float bottom, Paint paint) | 绘制矩形 |
drawRoundRect(RectF rect, float rx, float ry, Paint paint) | 绘制圆角矩形 |
drawText(String text, int start ,int end, Paint paint) | 绘制字符串 |
drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) | 沿着路径绘制字符串 |
clipRect(float left, float top, float right, float bottom) | 剪切一个矩形区域 |
clipRegion(Region region) | 剪切指定区域 |
>rotate(float degress, float px, float py): 对Canvas执行旋转变换.
>scale(float sx, float sy, float px, float py): 对Canvas执行缩放变换.
>skew(float sx, float sy): 对Canvas执行倾斜变换.
>translate(float dx, float dy): 移动Canvas.向右移动dx距离(dx为负数即向左移动);向下移动dy距离(dy为负数即向上移动).
Paint代表了Canvas上的画笔,因此Paint类主要用于设置绘制风格,包括画笔颜色.画笔笔触粗细,填充风格等.
Paint提供了如下所示的方法:
方法签名 | 简要说明 |
---|---|
setARGB(int a, int r, int g, int b)/setColor(int color) | 设置颜色 |
setAlpha(int a ) | 设置透明度 |
setAntiAlias(boolean aa) | 设置是否抗锯齿 |
setColor(int color) | 设置颜色 |
setPahtEffect(PathEffect cffect) | 设置绘制路径时的路径效果 |
setShader(Shader shader) | 设置画笔的填充效果 |
setShadowLayer(float radius, float dx, float dy, int color) | 设置阴影 |
setStrokeWidth(float width) | 设置画笔的笔触宽度 |
setStrokeJoin(Paint.Join join) | 设置画笔转弯处的连接风格 |
setStyle(Paint.Style style) | 设置Paint的填充风格 |
setTextAlign(Paint.Align align) | 设置绘制文本时的文字的对齐方式 |
setTextSize(float textSize) | 设置绘制文本时的文字大小 |
下面的MyView重写了onDraw(Canvas)方法,绘制了基本的几何图形.
- package com.example.canvastest.view;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.LinearGradient;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.graphics.RectF;
- import android.graphics.Shader;
- import android.util.AttributeSet;
- import android.view.View;
- public class MyView extends View {
- public MyView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
- public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
- public MyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public MyView(Context context) {
- super(context);
- }
- /**
- * 重写该方法,进行绘图
- */
- @SuppressLint("DrawAllocation")
- @Override
- protected void onDraw(Canvas canvas) {
- 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);
- // 绘制圆形
- canvas.drawCircle(40, 40, 30, paint);
- // 绘制正方形
- canvas.drawRect(10, 80, 70, 140, paint);
- // 绘制矩形
- canvas.drawRect(10, 150, 70, 190, paint);
- //
- RectF rectF1 = new RectF(10, 200, 70, 230);
- // 绘制圆角矩形
- canvas.drawRoundRect(rectF1, 15, 15, paint);
- //
- RectF rectF2 = new RectF(10, 240, 70, 270);
- // 绘制椭圆
- canvas.drawOval(rectF2, paint);
- // 定义一个Path对象,封闭成一个三角形
- Path path1 = new Path();
- // 设置起点
- path1.moveTo(10, 340);
- // 线路1
- path1.lineTo(70, 340);
- // 线路2
- path1.lineTo(40, 290);
- path1.close();
- // 根据Path进行绘制,绘制三角形
- canvas.drawPath(path1, paint);
- // 定义一个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();
- // 根据Path进行绘制,绘制三角形
- canvas.drawPath(path2, paint);
- // -------------设置填充风格后绘制---------------------------
- paint.setStyle(Paint.Style.FILL);
- paint.setColor(Color.RED);
- // 绘制圆形
- canvas.drawCircle(120, 40, 30, paint);
- // 绘制正方形
- canvas.drawRect(90, 80, 150, 140, paint);
- // 绘制矩形
- canvas.drawRect(90, 200, 150, 190, paint);
- // 绘制圆角矩形
- RectF rectF3 = new RectF(90, 200, 150, 230);
- canvas.drawRoundRect(rectF3, 15, 15, paint);
- // 绘制椭圆
- RectF rectF4 = new RectF(90, 240, 150, 270);
- canvas.drawOval(rectF4, paint);
- // 绘制三角形
- Path path3 = new Path();
- path3.moveTo(90, 340);
- path3.lineTo(150, 340);
- path3.lineTo(120, 290);
- path3.close();
- canvas.drawPath(path3, paint);
- // 绘制五角形
- 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);
- // -------------设置渐变器后绘制------------------
- // 为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);
- // 绘制圆形
- canvas.drawCircle(200, 40, 30, paint);
- // 绘制正方形
- canvas.drawRect(170, 80, 230, 140, paint);
- // 绘制矩形
- canvas.drawRect(170, 150, 230, 190, paint);
- // 绘制圆角矩形
- RectF rectF5 = new RectF(170, 200, 230, 230);
- canvas.drawRoundRect(rectF5, 15, 15, paint);
- // 绘制椭圆
- RectF rectF6 = new RectF(170, 240, 230, 270);
- canvas.drawOval(rectF6, paint);
- // 绘制三角形
- Path path6 = new Path();
- path6.moveTo(170, 340);
- path6.lineTo(230, 340);
- path6.lineTo(200, 290);
- path6.close();
- canvas.drawPath(path6, paint);
- // 绘制五角形
- Path path5 = new Path();
- path5.moveTo(186, 360);
- path5.lineTo(214, 360);
- path5.lineTo(230, 392);
- path5.lineTo(200, 420);
- path5.lineTo(170, 392);
- path5.close();
- canvas.drawPath(path5, paint);
- //----------设置字符大小后绘制-----------------
- paint.setTextSize(24);
- paint.setShader(null);
- //绘制7个字符串
- canvas.drawText("圆形", 240, 50, paint);
- canvas.drawText("正方形", 240, 120, paint);
- canvas.drawText("矩形", 240, 175, paint);
- canvas.drawText("圆角矩形", 240, 220, paint);
- canvas.drawText("椭圆形", 240, 260, paint);
- canvas.drawText("三角形", 240, 325, paint);
- canvas.drawText("五角形", 240, 390, paint);
- }
- }
package com.example.canvastest.view;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;public class MyView extends View {public MyView(Context context, AttributeSet attrs, int defStyleAttr,int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}public MyView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public MyView(Context context, AttributeSet attrs) {super(context, attrs);}public MyView(Context context) {super(context);}/*** 重写该方法,进行绘图*/@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {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);// 绘制圆形canvas.drawCircle(40, 40, 30, paint);// 绘制正方形canvas.drawRect(10, 80, 70, 140, paint);// 绘制矩形canvas.drawRect(10, 150, 70, 190, paint);//RectF rectF1 = new RectF(10, 200, 70, 230);// 绘制圆角矩形canvas.drawRoundRect(rectF1, 15, 15, paint);//RectF rectF2 = new RectF(10, 240, 70, 270);// 绘制椭圆canvas.drawOval(rectF2, paint);// 定义一个Path对象,封闭成一个三角形Path path1 = new Path();// 设置起点path1.moveTo(10, 340);// 线路1path1.lineTo(70, 340);// 线路2path1.lineTo(40, 290);path1.close();// 根据Path进行绘制,绘制三角形canvas.drawPath(path1, paint);// 定义一个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();// 根据Path进行绘制,绘制三角形canvas.drawPath(path2, paint);// -------------设置填充风格后绘制---------------------------paint.setStyle(Paint.Style.FILL);paint.setColor(Color.RED);// 绘制圆形canvas.drawCircle(120, 40, 30, paint);// 绘制正方形canvas.drawRect(90, 80, 150, 140, paint);// 绘制矩形canvas.drawRect(90, 200, 150, 190, paint);// 绘制圆角矩形RectF rectF3 = new RectF(90, 200, 150, 230);canvas.drawRoundRect(rectF3, 15, 15, paint);// 绘制椭圆RectF rectF4 = new RectF(90, 240, 150, 270);canvas.drawOval(rectF4, paint);// 绘制三角形Path path3 = new Path();path3.moveTo(90, 340);path3.lineTo(150, 340);path3.lineTo(120, 290);path3.close();canvas.drawPath(path3, paint);// 绘制五角形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);// -------------设置渐变器后绘制------------------// 为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);// 绘制圆形canvas.drawCircle(200, 40, 30, paint);// 绘制正方形canvas.drawRect(170, 80, 230, 140, paint);// 绘制矩形canvas.drawRect(170, 150, 230, 190, paint);// 绘制圆角矩形RectF rectF5 = new RectF(170, 200, 230, 230);canvas.drawRoundRect(rectF5, 15, 15, paint);// 绘制椭圆RectF rectF6 = new RectF(170, 240, 230, 270);canvas.drawOval(rectF6, paint);// 绘制三角形Path path6 = new Path();path6.moveTo(170, 340);path6.lineTo(230, 340);path6.lineTo(200, 290);path6.close();canvas.drawPath(path6, paint);// 绘制五角形Path path5 = new Path();path5.moveTo(186, 360);path5.lineTo(214, 360);path5.lineTo(230, 392);path5.lineTo(200, 420);path5.lineTo(170, 392);path5.close();canvas.drawPath(path5, paint);//----------设置字符大小后绘制-----------------paint.setTextSize(24);paint.setShader(null);//绘制7个字符串canvas.drawText("圆形", 240, 50, paint);canvas.drawText("正方形", 240, 120, paint);canvas.drawText("矩形", 240, 175, paint);canvas.drawText("圆角矩形", 240, 220, paint);canvas.drawText("椭圆形", 240, 260, paint);canvas.drawText("三角形", 240, 325, paint);canvas.drawText("五角形", 240, 390, paint);}}
Path类: Android提供的Path是一个非常有用的类,它可以预先在View上将N个点连成一条"路径",然后调用Canvas的drawPath(Path path, Paint paint)即可沿着路径绘制图形.实际上Android还为路径绘制提供了PathEffect来定义绘制效果,PathEffect包含了如下子类(每个子类代表一种绘制效果):
Corner PathEffect
Discrete PathEffect
Dash PathEffect
Path Dash PathEffect
Compose PathEffect
Sum PathEffect
这些绘制效果使用语言来表述总显得有些空洞,下面通过一个程序来了解一下绘制效果.接下来的程序绘制7条路径,分别示范了不适用效果和使用上面6种效果的示意.
- package com.example.canvastest.view;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.ComposePathEffect;
- import android.graphics.CornerPathEffect;
- import android.graphics.DashPathEffect;
- import android.graphics.DiscretePathEffect;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.graphics.PathDashPathEffect;
- import android.graphics.PathEffect;
- import android.graphics.SumPathEffect;
- import android.util.AttributeSet;
- import android.view.View;
- /**
- * 使用Path绘制路径
- * @author Administrator
- *
- */
- public class MyPathView extends View {
- private float phase;
- private PathEffect[] pathEffects = new PathEffect[7];
- private int[] colors;
- private Path path;
- private Paint paint;
- public MyPathView(Context context) {
- this(context, null);
- }
- public MyPathView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public MyPathView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- paint = new Paint();
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(4);
- // 创建并初始化Path
- path = new Path();
- path.moveTo(0, 0);
- for (int i = 0; i < 15; i++) {
- // 生成15个点,随机生成他们的Y坐标,并将它们练成一条Path
- path.lineTo(i * 20, (float) Math.random() * 60);
- }
- // 初始化7个颜色
- colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN,
- Color.MAGENTA, Color.RED, Color.YELLOW };
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- ///将背景填充为白色
- canvas.drawColor(Color.WHITE);
- //-------下面开始初始化7种路径效果--------
- //不使用路径效果
- pathEffects[0] = null;
- //使用CornerPathEffect路径效果//角路径效应
- pathEffects[1] = new CornerPathEffect(10);
- //使用DiscretePathEffect路径效果//离散路径效应
- pathEffects[2] = new DiscretePathEffect(3.0f, 5.0f);
- //DashPathEffect//短跑路径效应
- pathEffects[3] = new DashPathEffect(new float[]{20, 10, 5, 10}, phase);
- //PathDashPathEffect//短跑的路径路径效应
- Path p = new Path();
- p.addRect(0, 0, 8, 8, Path.Direction.CCW);
- pathEffects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE);
- //ComposePathEffect//组成的路径效应
- pathEffects[5] = new ComposePathEffect(pathEffects[2], pathEffects[4]);
- //SumPathEffect//总和路径效应
- pathEffects[6] = new SumPathEffect(pathEffects[4], pathEffects[3]);
- //将画布移动到(8,8)出绘制
- canvas.translate(8, 8);
- //依次使用7种不同路径效果,7种颜色来绘制路径
- for (int i = 0; i < pathEffects.length; i++) {
- paint.setPathEffect(pathEffects[i]);
- paint.setColor(colors[i]);
- canvas.drawPath(path, paint);
- canvas.translate(0, 60);
- }
- //改变phase值,形成动画效果
- phase += 1;
- invalidate();
- }
- }
package com.example.canvastest.view;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposePathEffect;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.DiscretePathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathDashPathEffect;
import android.graphics.PathEffect;
import android.graphics.SumPathEffect;
import android.util.AttributeSet;
import android.view.View;/*** 使用Path绘制路径* @author Administrator**/
public class MyPathView extends View {private float phase;private PathEffect[] pathEffects = new PathEffect[7];private int[] colors;private Path path;private Paint paint;public MyPathView(Context context) {this(context, null);}public MyPathView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyPathView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(4);// 创建并初始化Pathpath = new Path();path.moveTo(0, 0);for (int i = 0; i < 15; i++) {// 生成15个点,随机生成他们的Y坐标,并将它们练成一条Pathpath.lineTo(i * 20, (float) Math.random() * 60);}// 初始化7个颜色colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN,Color.MAGENTA, Color.RED, Color.YELLOW };}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);///将背景填充为白色canvas.drawColor(Color.WHITE);//-------下面开始初始化7种路径效果--------//不使用路径效果pathEffects[0] = null;//使用CornerPathEffect路径效果//角路径效应pathEffects[1] = new CornerPathEffect(10);//使用DiscretePathEffect路径效果//离散路径效应pathEffects[2] = new DiscretePathEffect(3.0f, 5.0f);//DashPathEffect//短跑路径效应pathEffects[3] = new DashPathEffect(new float[]{20, 10, 5, 10}, phase);//PathDashPathEffect//短跑的路径路径效应Path p = new Path();p.addRect(0, 0, 8, 8, Path.Direction.CCW);pathEffects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE);//ComposePathEffect//组成的路径效应pathEffects[5] = new ComposePathEffect(pathEffects[2], pathEffects[4]);//SumPathEffect//总和路径效应pathEffects[6] = new SumPathEffect(pathEffects[4], pathEffects[3]);//将画布移动到(8,8)出绘制canvas.translate(8, 8);//依次使用7种不同路径效果,7种颜色来绘制路径for (int i = 0; i < pathEffects.length; i++) {paint.setPathEffect(pathEffects[i]);paint.setColor(colors[i]);canvas.drawPath(path, paint);canvas.translate(0, 60);}//改变phase值,形成动画效果phase += 1;invalidate();}}
除此之外,Android的Canvas还提供了一个DrawTextOnPath(String text,Path path, float hOffset, float vOffset, Paint paint)方法,该方法可以沿着Path绘制文本,其中hOffset参数指定水平偏移,vOffset参数指定垂直偏移.
- package com.example.canvastest.view;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Paint.Align;
- import android.graphics.Path;
- import android.graphics.RectF;
- import android.util.AttributeSet;
- import android.view.View;
- /**
- * 使用drawTextOnPaht,沿着Path(路径)绘制文本
- *
- * @author Administrator
- */
- public class MyPathTextView extends View {
- final String DRAW_STR = "绘制文本";
- private Path[] paths = new Path[3];
- Paint paint;
- public MyPathTextView(Context context) {
- this(context, null);
- }
- public MyPathTextView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public MyPathTextView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- paths[0] = new Path();
- paths[0].moveTo(0, 0);
- for (int i = 0; i < 7; i++) {
- // 生成7个点,随机生成它们的y坐标,并将它们连成一条path
- paths[0].lineTo(1 * 30, (float) Math.random() * 30);
- }
- 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);
- // 初始化画笔
- paint = new Paint();
- paint.setAntiAlias(true);
- paint.setColor(Color.CYAN);
- paint.setStrokeWidth(1);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- canvas.drawColor(Color.WHITE);
- canvas.translate(40, 40);
- // 设置从右边开始绘制(右对齐)
- paint.setTextAlign(Paint.Align.RIGHT);
- paint.setTextSize(20);
- // 绘制路径
- 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进行坐标变换:画布下移60
- canvas.translate(0, 60);
- // 绘制路径
- 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);
- // 绘制路径
- paint.setStyle(Paint.Style.STROKE);
- canvas.drawPath(paths[2], paint);
- // 沿着路径绘制一段文本
- paint.setStyle(Paint.Style.FILL);
- canvas.drawTextOnPath(DRAW_STR, paths[2], -10, 20, paint);
- }
- }
package com.example.canvastest.view;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;/*** 使用drawTextOnPaht,沿着Path(路径)绘制文本* * @author Administrator*/
public class MyPathTextView extends View {final String DRAW_STR = "绘制文本";private Path[] paths = new Path[3];Paint paint;public MyPathTextView(Context context) {this(context, null);}public MyPathTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyPathTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paths[0] = new Path();paths[0].moveTo(0, 0);for (int i = 0; i < 7; i++) {// 生成7个点,随机生成它们的y坐标,并将它们连成一条pathpaths[0].lineTo(1 * 30, (float) Math.random() * 30);}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);// 初始化画笔paint = new Paint();paint.setAntiAlias(true);paint.setColor(Color.CYAN);paint.setStrokeWidth(1);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.WHITE);canvas.translate(40, 40);// 设置从右边开始绘制(右对齐)paint.setTextAlign(Paint.Align.RIGHT);paint.setTextSize(20);// 绘制路径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进行坐标变换:画布下移60canvas.translate(0, 60);// 绘制路径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进行坐标变换:画布下移120canvas.translate(0, 120);// 绘制路径paint.setStyle(Paint.Style.STROKE);canvas.drawPath(paths[2], paint);// 沿着路径绘制一段文本paint.setStyle(Paint.Style.FILL);canvas.drawTextOnPath(DRAW_STR, paths[2], -10, 20, paint);}}
下面是一个使用双缓冲机制实现的画面板例子
- package com.example.canvastest.view;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- public class DrawView extends View {
- float preX;
- float preY;
- private Paint paint = null;
- final int VIEW_WIDTH = 320;
- final int VIEW_HEIGHT = 480;
- // 定义一个内存中的图片,该图片将作为缓冲区
- Bitmap cacheBitmap = null;
- // 定义cachebitmap上的canvas对象
- Canvas cacheCanvas = null;
- Path path = null;
- public DrawView(Context context) {
- this(context, null);
- }
- public DrawView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- // 设置画笔的颜色
- paint = new Paint(Paint.DITHER_FLAG);
- paint.setColor(Color.RED);
- // 设置画笔的风格
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(1);
- // 抗锯齿
- paint.setAntiAlias(true);
- paint.setDither(true);
- // 创建一个与该View相同大小的缓冲区
- cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT,
- Bitmap.Config.ARGB_8888);
- // 设置cacheCanvas将会绘制到内存中的cacheBitmap上
- cacheCanvas = new Canvas();
- path = new Path();
- cacheCanvas.setBitmap(cacheBitmap);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- path.moveTo(x, y);
- preX = x;
- preY = x;
- break;
- case MotionEvent.ACTION_MOVE:
- path.quadTo(preX, preY, x, y);
- preX = x;
- preY = y;
- break;
- case MotionEvent.ACTION_UP:
- cacheCanvas.drawPath(path, paint);
- path.reset();
- break;
- }
- invalidate();
- // 返回true表明处理方法已经处理该事件
- return true;
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Paint paint = new Paint();
- // 将该bitmap绘制到该View组件上
- canvas.drawBitmap(cacheBitmap, 0, 0, paint);
- // 沿着path绘制
- canvas.drawPath(path, paint);
- }
- }
package com.example.canvastest.view;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class DrawView extends View {float preX;float preY;private Paint paint = null;final int VIEW_WIDTH = 320;final int VIEW_HEIGHT = 480;// 定义一个内存中的图片,该图片将作为缓冲区Bitmap cacheBitmap = null;// 定义cachebitmap上的canvas对象Canvas cacheCanvas = null;Path path = null;public DrawView(Context context) {this(context, null);}public DrawView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// 设置画笔的颜色paint = new Paint(Paint.DITHER_FLAG);paint.setColor(Color.RED);// 设置画笔的风格paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(1);// 抗锯齿paint.setAntiAlias(true);paint.setDither(true);// 创建一个与该View相同大小的缓冲区cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT,Bitmap.Config.ARGB_8888);// 设置cacheCanvas将会绘制到内存中的cacheBitmap上cacheCanvas = new Canvas();path = new Path();cacheCanvas.setBitmap(cacheBitmap);}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:path.moveTo(x, y);preX = x;preY = x;break;case MotionEvent.ACTION_MOVE:path.quadTo(preX, preY, x, y);preX = x;preY = y;break;case MotionEvent.ACTION_UP:cacheCanvas.drawPath(path, paint);path.reset();break;}invalidate();// 返回true表明处理方法已经处理该事件return true;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();// 将该bitmap绘制到该View组件上canvas.drawBitmap(cacheBitmap, 0, 0, paint);// 沿着path绘制canvas.drawPath(path, paint);}}
一个弹球游戏例子
- package com.example.canvastest;
- import java.util.Random;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.os.Bundle;
- import android.os.Handler;
- import android.util.AttributeSet;
- import android.util.DisplayMetrics;
- import android.view.Display;
- import android.view.KeyEvent;
- import android.view.View;
- import android.view.View.OnKeyListener;
- import android.view.Window;
- import android.view.WindowManager;
- public class PinBallActivity extends Activity {
- /** 桌面的宽度 */
- private int tableWidth;
- /** 桌面的高度 */
- private int tableHeight;
- /** 随机数生成器 **/
- private Random random = new Random();
- /** 球拍的垂直位置 */
- private int racketY;
- /** 球拍的水平位置 */
- private int racketX = random.nextInt(200);
- /** 球拍的宽度 */
- private final int RACKET_WIDTH = 70;
- /** 球拍的高度 */
- private final int RACKET_HEIGHT = 20;
- /** 小球的大小 */
- private int BALL_SIZE = 12;
- /** 小球的X坐标 */
- private int ballX = random.nextInt(200) + 20;
- /** 小球的Y坐标 */
- private int ballY = random.nextInt(10) + 20;
- /**返回一个-0.5~0.5的比率,用于控制小球的运行方向*/
- private double xyRate = random.nextDouble()- 0.5;
- /**小球的纵向运行速度*/
- private int ySpeed = 10;
- /**小球的横向运行速度*/
- private int xSpeed = (int) (ySpeed * xyRate * 2);
- /*** 游戏是否结束的游标 */
- private boolean isLose = false;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 去掉窗口标题
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- // 全屏显示
- getWindow().setFlags(WindowManager.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.MATCH_PARENT);
- // 创建FameView组件
- final GameView gameView = new GameView(this);
- setContentView(gameView);
- // 获取窗口管理器
- WindowManager manager = getWindowManager();
- // 获取密度
- Display display = manager.getDefaultDisplay();
- DisplayMetrics displayMetrics = new DisplayMetrics();
- display.getMetrics(displayMetrics);
- // 获得屏幕的宽和高
- tableWidth = displayMetrics.widthPixels;
- tableHeight = displayMetrics.heightPixels;
- // 初始化球拍的垂直位置
- racketY = tableHeight - 80;
- final Handler handler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- if (msg.what == 0x123) {
- gameView.invalidate();
- }
- };
- };
- gameView.setOnKeyListener(new OnKeyListener() {
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // 获取由那个键触发的事件
- switch (event.getAction()) {
- // 控制挡板左移
- case KeyEvent.KEYCODE_A:
- if (racketX > 0)
- racketX -= 10;
- break;
- // 控制挡板右移
- case KeyEvent.KEYCODE_D:
- if (racketX < tableWidth - tableWidth)
- racketX += 10;
- break;
- }
- // 通知GameView重绘
- gameView.invalidate();
- return true;
- }
- });
- final Timer timer = new Timer();
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- //如果小球碰到左边边框
- if(ballX <= 0 || ballX >= tableWidth - BALL_SIZE){
- xSpeed = -xSpeed;
- }
- //如果小球高度超出了球拍的位置,且横向不在球拍的范围之内,游戏结束
- if(ballY >= racketY - BALL_SIZE && (ballX < racketX || ballX > racketX + RACKET_WIDTH)){
- timer.cancel();
- //设置游戏是否结束的旗标为true
- isLose = true;
- }
- //如果小球位于球拍之内,且到达球拍位置,小球反弹
- else if(ballY <= 0 || (ballY >= racketY - BALL_SIZE && ballX >racketX && ballX <= racketX + RACKET_WIDTH)){
- ySpeed = -ySpeed;
- }
- //小球的坐标增加
- ballX += xSpeed;
- ballY += ySpeed;
- //发送消息,通知系统重绘组件
- handler.sendEmptyMessage(0x123);
- }
- }, 0, 100);
- }
- class GameView extends View {
- Paint paint = new Paint();
- public GameView(Context context) {
- this(context, null);
- }
- public GameView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- // 接收焦点
- setFocusable(true);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- // 设置样式
- paint.setStyle(Paint.Style.FILL);
- // 抗锯齿
- paint.setAntiAlias(true);
- // 如果游戏已经结束
- if (isLose) {
- // 颜色
- paint.setColor(Color.RED);
- ;
- // 字体大小
- paint.setTextSize(40);
- canvas.drawText("游戏结束", 50, 200, paint);
- }
- // 如果游戏还没有结束
- else {
- // 设置颜色,绘制小球
- paint.setColor(Color.rgb(240, 240, 80));
- canvas.drawCircle(ballX, ballY, BALL_SIZE, paint);
- // 设置颜色,绘制球拍
- paint.setColor(Color.rgb(80, 80, 200));
- canvas.drawRect(racketX, racketY, racketX + RACKET_WIDTH,
- racketY + RACKET_HEIGHT, paint);
- }
- }
- }
- }
package com.example.canvastest;import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.Window;
import android.view.WindowManager;public class PinBallActivity extends Activity {/** 桌面的宽度 */private int tableWidth;/** 桌面的高度 */private int tableHeight;/** 随机数生成器 **/private Random random = new Random();/** 球拍的垂直位置 */private int racketY;/** 球拍的水平位置 */private int racketX = random.nextInt(200);/** 球拍的宽度 */private final int RACKET_WIDTH = 70;/** 球拍的高度 */private final int RACKET_HEIGHT = 20;/** 小球的大小 */private int BALL_SIZE = 12;/** 小球的X坐标 */private int ballX = random.nextInt(200) + 20;/** 小球的Y坐标 */private int ballY = random.nextInt(10) + 20;/**返回一个-0.5~0.5的比率,用于控制小球的运行方向*/private double xyRate = random.nextDouble()- 0.5;/**小球的纵向运行速度*/private int ySpeed = 10;/**小球的横向运行速度*/private int xSpeed = (int) (ySpeed * xyRate * 2); /*** 游戏是否结束的游标 */private boolean isLose = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 去掉窗口标题requestWindowFeature(Window.FEATURE_NO_TITLE);// 全屏显示getWindow().setFlags(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT);// 创建FameView组件final GameView gameView = new GameView(this);setContentView(gameView);// 获取窗口管理器WindowManager manager = getWindowManager();// 获取密度Display display = manager.getDefaultDisplay();DisplayMetrics displayMetrics = new DisplayMetrics();display.getMetrics(displayMetrics);// 获得屏幕的宽和高tableWidth = displayMetrics.widthPixels;tableHeight = displayMetrics.heightPixels;// 初始化球拍的垂直位置racketY = tableHeight - 80;final Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {if (msg.what == 0x123) {gameView.invalidate();}};};gameView.setOnKeyListener(new OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {// 获取由那个键触发的事件switch (event.getAction()) {// 控制挡板左移case KeyEvent.KEYCODE_A:if (racketX > 0)racketX -= 10;break;// 控制挡板右移case KeyEvent.KEYCODE_D:if (racketX < tableWidth - tableWidth)racketX += 10;break;}// 通知GameView重绘gameView.invalidate();return true;}});final Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {//如果小球碰到左边边框if(ballX <= 0 || ballX >= tableWidth - BALL_SIZE){xSpeed = -xSpeed;}//如果小球高度超出了球拍的位置,且横向不在球拍的范围之内,游戏结束if(ballY >= racketY - BALL_SIZE && (ballX < racketX || ballX > racketX + RACKET_WIDTH)){timer.cancel();//设置游戏是否结束的旗标为trueisLose = true;}//如果小球位于球拍之内,且到达球拍位置,小球反弹else if(ballY <= 0 || (ballY >= racketY - BALL_SIZE && ballX >racketX && ballX <= racketX + RACKET_WIDTH)){ySpeed = -ySpeed;}//小球的坐标增加ballX += xSpeed;ballY += ySpeed;//发送消息,通知系统重绘组件handler.sendEmptyMessage(0x123);}}, 0, 100);}class GameView extends View {Paint paint = new Paint();public GameView(Context context) {this(context, null);}public GameView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public GameView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// 接收焦点setFocusable(true);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 设置样式paint.setStyle(Paint.Style.FILL);// 抗锯齿paint.setAntiAlias(true);// 如果游戏已经结束if (isLose) {// 颜色paint.setColor(Color.RED);;// 字体大小paint.setTextSize(40);canvas.drawText("游戏结束", 50, 200, paint);}// 如果游戏还没有结束else {// 设置颜色,绘制小球paint.setColor(Color.rgb(240, 240, 80));canvas.drawCircle(ballX, ballY, BALL_SIZE, paint);// 设置颜色,绘制球拍paint.setColor(Color.rgb(80, 80, 200));canvas.drawRect(racketX, racketY, racketX + RACKET_WIDTH,racketY + RACKET_HEIGHT, paint);}}}}
这篇关于Android Canvas 和Paint的用法 转自http://blog.csdn.net/u010947098/article/details/44574171的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!