第一节:http://blog.csdn.net/bobo8945510/article/details/53197727 —自定义View—自定义属性及引用
第二节:http://blog.csdn.net/bobo8945510/article/details/53203233 自定义view02—图形绘制
第四节:http://blog.csdn.net/bobo8945510/article/details/53256863 Android实现手写板和涂鸦
第五节:http://blog.csdn.net/bobo8945510/article/details/53257232 环形进度条
第六章:http://blog.csdn.net/bobo8945510/article/details/53374319 自定义折线图
path类是一个非常有用的类,他可以预先在view上讲N个点连成一条“路径”,然后调用Canvas的drawPath(path,paint)即可沿着路径绘制图形,并且Android还为路径提供了pathEffect来绘制效果,pathEffect包含了如下子类
-ComposePathEffect
-ComnerPathEffect
-DashPathEffect
-DiscretePathEffect
-PathDashPathEffect
-SunPathEffect
package tester.ermu.com.canvasdemo;
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;
/**
* Created by ENZ on 2016/11/17.
*/
public class PathText extends View {
private float phase;
//线条的集合,
PathEffect[] effects = new PathEffect[7];
int[] colors;
private Paint paint;
Path path;
public PathText(Context context, AttributeSet attrs) {
super(context, attrs);
//----------------------第一步-------------------------------
//创建一个画笔对象,设置画笔类型和画笔的大小
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(8);
//------------------------第二步-----------------------------
/*
创建一个Path对象
* 起始点为moveTo(0, 0)
* */
path = new Path();
path.moveTo(0, 0);
//--------------------------第三步---------------------------
/*
* /生成50个点,随机生成它们的Y坐标,并将它们连成一条Path
* */
for (int i = 1; i <= 50; i++)
{
path.lineTo(i * 20, (float) Math.random() *100);
}
// 初始化7个颜色
colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN,
Color.GREEN, Color.MAGENTA, Color.RED, Color.GRAY };
}
public PathText(Context context){
super(context);
}
//-------------------------第四步----------------------------
@Override
protected void onDraw(Canvas canvas){
// 将背景填充成白色
canvas.drawColor(Color.WHITE);
// ---------------------------------------------------
//第一条线,什么效果都不加
/*
* 效果:无
* */
effects[0] = null;
// ---------------------------------------------------
/*第二条线
* 使用CornerPathEffect路径效果
* 效果:拐角平滑,平滑度为10
* */
effects[1] = new CornerPathEffect(10);
// ---------------------------------------------------
/*第三条线
* 初始化DiscretePathEffect,使得在原来路径的基础上发生打散效果。
* 通过构造DiscretePathEffect(float segmentLength,float deviation)
* segmentLength指定最大的段长,deviation指定偏离量。
* */
effects[2] = new DiscretePathEffect(1.0f, 5.0f);
// ---------------------------------------------------
/*第四条线
* 初始化DashPathEffect
* 这个类的作用就是将Path的线段虚线化。
* 构造函数为DashPathEffect(float[] intervals, float offset)
* 其中intervals为虚线的ON和OFF数组,该数组的length必须大于等于2,phase为绘制时的偏移量。
* */
effects[3] = new DashPathEffect(new float[] { 20, 10, 5, 10 },phase);
// ---------------------------------------------------
/*第五条线
* 使用Path图形来填充当前的路径
* 构造函数为PathDashPathEffect (Path shape, float advance, float phase,PathDashPathEffect.Stylestyle)。
* shape则是指填充图形,advance指每个图形间的间距,phase为绘制时的偏移量,
*
* style为该类自由的枚举值,有三种情况:Style.ROTATE、Style.MORPH和
* ROTATE的情况下,线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行旋转,
* MORPH时图形会以发生拉伸或压缩等变形的情况与下一段相连接,
* TRANSLATE时,图形会以位置平移的方式与下一段相连接。
* */
Path p = new Path();
p.addRect(0, 0, 8, 8, Path.Direction.CCW);
effects[4] = new PathDashPathEffect(p, 12, phase,PathDashPathEffect.Style.ROTATE);
// ---------------------------------------------------
/*第六条线
* 这个类需要两个PathEffect参数来构造一个实例
* ComposePathEffect (PathEffect outerpe,PathEffect innerpe)表现时
* 会首先将innerpe表现出来,然后再在innerpe的基础上去增加outerpe的效果。
*
* 下面我就是用了effects[2], effects[4]
* */
// 初始化ComposePathEffect
effects[5] = new ComposePathEffect(effects[2], effects[4]);
// ---------------------------------------------------
/*第七条线
* 这个类也需要两个PathEffect作为参数SumPathEffect(PathEffect first,PathEffect second),
* 但与ComposePathEffect不同的是,在表现时,会分别对两个参数的效果各自独立进行表现,然后将两个效果简单的重叠在一起显示出来。
* */
effects[6] = new SumPathEffect(effects[4], effects[3]);
// ---------------------------------------------------
// 将画布移动到(8、8)处开始绘制
canvas.translate(16, 100);
// 依次使用7种不同路径效果、7种不同的颜色来绘制路径
for (int i = 0; i < effects.length; i++){
paint.setPathEffect(effects[i]);
paint.setColor(colors[i]);
canvas.drawPath(path, paint);
canvas.translate(0, 160);
}
// 改变phase值,形成动画效果
// ---------------------------------------------------
/*
* 使用重新绘制方法invalidate();,偏移量加一,形成运行效果
* */
phase += 1;
invalidate();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 连接路径到点[100,100]
mPath.lineTo(100, 100);
// 绘制路径
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
mPath.moveTo(100, 100);
// 连接路径到点
mPath.lineTo(300, 100);
mPath.lineTo(400, 200);
mPath.lineTo(200, 200);
// 绘制路径
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
mPath.moveTo(100, 100);
// 连接路径到点
mPath.lineTo(300, 100);
mPath.lineTo(400, 200);
mPath.lineTo(200, 200);
// 闭合曲线
mPath.close();
// 绘制路径
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 移动起点至[100,100]
mPath.moveTo(100, 100);
// 连接路径到点
mPath.quadTo(200, 200, 300, 100);
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 移动起点至[100,100]
mPath.moveTo(100, 100);
// 连接路径到点
mPath.cubicTo(200, 200, 300, 0, 400, 100);
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 移动起点至[100,100]
mPath.moveTo(100, 100);
// 连接路径到点
RectF oval = new RectF(100, 100, 200, 200);
mPath.arcTo(oval, 0, 90);
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 移动起点至[100,100]
mPath.moveTo(100, 100);
// 连接路径到点
RectF oval = new RectF(100, 100, 200, 200);
mPath.arcTo(oval, 0, 90,true);
canvas.drawPath(mPath, mPaint);
}
rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
rLineTo(float dx, float dy)
rMoveTo(float dx, float dy)
rQuadTo(float dx1, float dy1, float dx2, float dy2)
例如: 起点(100,100)到终点(200,200)
XXXTo绘制的距离就是,这里的move和lineTo的坐标都是对于画布左上角(0,0)来说。100到200的距离,绘制的总长度为00到200,也就是200距离
而rXXXTo绘制的距离就是相对于100起点,再绘制200的距离。绘制的总长度就是300
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 移动点至[100,100]
mPath.moveTo(100, 100);
// 连接路径到点
mPath.lineTo(200, 200);
canvas.drawPath(mPath, mPaint);
}
XXXTo方法可以连接Path中的曲线,而Path提供的另一系列addXXX方法则可以让我们直接往Path中添加一些曲线,比如
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
// 实例化路径
mPath = new Path();
// 移动点至[100,100]
mPath.moveTo(100, 100);
// 连接路径到点
mPath.lineTo(200, 200);
// 添加一条弧线到Path中
RectF oval = new RectF(100, 100, 300, 400);
mPath.addArc(oval, 0, 90);
canvas.drawPath(mPath, mPaint);
}
addCircle(float x, float y, float radius, Path.Direction dir)
addOval(float left, float top, float right, float bottom, Path.Direction dir)
addRect(float left, float top, float right, float bottom, Path.Direction dir)
addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Path.Direction dir)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
// 实例化路径
mPath = new Path();
// 移动起点至[100,100]
mPath.moveTo(100, 100);
// 添加一条弧线到Path中
RectF oval = new RectF(100, 100, 300, 400);
mPath.addOval(oval, Path.Direction.CW);
canvas.drawPath(mPath, mPaint);
mPaint.setTextSize(50);
// 绘制路径上的文字
canvas.drawTextOnPath("123456789", mPath, 0, 0, mPaint);
}
上面代码是借鉴他的文章http://www.cnblogs.com/tianzhijiexian/p/4301113.html