我们知道Android中Canvas类对象可以进行绘制事物,里面有一个方法为canvas.drawPath方法,这个方法就是用来绘制我们的自定义Path对象。Path对象很有用,我们可以绘制一些特殊的动画效果,文字吸附效果等等。所以我们需要来学习下Path对象的使用。
详细请参考:http://blog.sina.com.cn/s/blog_4d9c3fec0102vyhs.html
Path对象的方法:
一、构造函数
1、无参构造函数
public Path() {
mNativePath = init1();
}
创建一个空的Path对象。
public Path(Path src) {
long valNative = 0;
if (src != null) {
valNative = src.mNativePath;
isSimplePath = src.isSimplePath;
if (src.rects != null) {
rects = new Region(src.rects);
}
}
mNativePath = init2(valNative);
}
创建一个将非空的含有src的Path对象。
二、成员函数
1、 public void moveTo(float x, float y)
移动绘制的起点,从点(x,y)点开始进行绘制。
2、 public void lineTo(float x, float y)
连接起始点与点(x,y)的直线,如果没有使用moveTo则起始点默认为(0,0)。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
mPath.lineTo(300,300);
canvas.drawPath(mPath,mPaint);
}
实例2:我们在lineTo之前添加MoveTo方法。
3、public void rMoveTo(float dx, float dy)
在绘制线的终点的基础上移动(dx,dy)得到新的起始点。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
mPath.lineTo(100,100);
mPath.rMoveTo(50,50);
mPath.lineTo(300,300);
canvas.drawPath(mPath,mPaint);
}
4、public void rLineTo(float dx, float dy)
与lineTo功能类似,但是是在上个线的终点基础上进行绘制,不是lineTo的从(0,0)开始。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
mPath.lineTo(100,50);
mPath.rLineTo(200,300);
canvas.drawPath(mPath,mPaint);
}
5、public void quadTo(float x1, float y1, float x2, float y2)
根据两个控制点绘制贝塞尔曲线。如果没有使用moveTo指定起点,起点默认为(0,0),即(0,0)到(x1,y1)之间绘制贝塞尔曲线,(x1,y1)到(x2,y2)之间绘制贝塞尔曲线。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
mPath.quadTo(100,50,300,500);
canvas.drawPath(mPath,mPaint);
}
6、 public void cubicTo(float x1, float y1, float x2, float y2,
float x3, float y3)
通过三个控制点绘制贝塞尔曲线。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
//为了增强效果对比,我们绘制出三个控制点之间对应的直线
mPath.lineTo(100,50);
mPath.lineTo(200, 300);
mPath.lineTo(400, 220);
canvas.drawPath(mPath, mPaint);
mPath = new Path();
//绘制贝塞尔曲线
mPath.cubicTo(100, 50, 200, 300, 400, 220);
canvas.drawPath(mPath,mPaint);
}
7、public void rQuadTo(float dx1, float dy1, float dx2, float dy2)
方法同quadTo,主要不同是这里的dx、dy表示的是坐标的差值,类似上面的rlineTo,相对上一个点的dx、dy的计算后的终点。但是注意此时的dx、dy都是相对于起点,即二者的起点都是相同的,(dx2,dy2)不是相对于(dx1,dy1)。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
//为了增强效果对比,我们绘制出三个控制点之间对应的直线
mPath.rLineTo(100,100);
mPath.lineTo(400, 220);
canvas.drawPath(mPath, mPaint);
mPath = new Path();
//绘制贝塞尔曲线
mPath.rQuadTo(100, 100,400, 220);
canvas.drawPath(mPath,mPaint);
}
最终的终点是(400,220),所以也印证了dx2、dy2与dx1、dy1有相同的起点。
8、public void rCubicTo(float x1, float y1, float x2, float y2,
float x3, float y3)效果与上相同,就不演示了。
9、public void arcTo(RectF oval, float startAngle, float sweepAngle)
用于绘制圆弧。
public void addRect(float left, float top, float right, float bottom, Direction dir)添加矩形
实例9:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
RectF rectF = new RectF(100,100,300,300);
mPath.addRect(rectF, Path.Direction.CW);
mPath.addArc(rectF,0,360);
canvas.drawPath(mPath,mPaint);
}
10、 public void addOval(RectF oval, Direction dir)
添加一个闭环的圆环路径。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
RectF rectF = new RectF(100,100,400,300);
mPath.addRect(rectF, Path.Direction.CW);
mPath.addOval(rectF,Path.Direction.CW);
canvas.drawPath(mPath,mPaint);
}
11、public void addCircle(float x, float y, float radius, Direction dir)
添加一个圆形路径。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
mPath.addCircle(200,200,100,Path.Direction.CW);
canvas.drawPath(mPath,mPaint);
}
12、public void addRoundRect(RectF rect, float rx, float ry, Direction dir)
添加圆角矩形路径。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
RectF rectF = new RectF(100,100,400,300);
mPath.addRoundRect(rectF,20,20, Path.Direction.CW);
canvas.drawPath(mPath,mPaint);
}
13、public void offset(float dx, float dy, Path dst)
public void offset(float dx, float dy)
通过dx、dy进行移动path,如果dst为null,则修改原路径,即src
14、 public void reset(),清空path路径中的信息。
15、 public void rewind(),rewind当前path,清除掉所有直线,曲线,但是保留它内部的数据结构,以便更好的重新使用
补充:
1、Path.Direction
用来指定添加到path中的模型(比如方形,椭圆)的闭合方向,有两个值
CCW 表示逆时针
CW 表示顺时针
2、FillType表示填充模式,它的填充模式和Paint的不同,它有四个枚举值。Inverse就是去反之意。
FillType.WINDING,默认值,当两个图形香蕉,正常相交情况显示
FillType.EVEN_ODD,取path所在并不相交的区域
FillType.INVERSE_WINDING,取path的外部区域
FillType.INVERSE_EVEN_ODD:取path外部和相交区域
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.parseColor("#ff0000"));
mPath.addRect(100, 100, 300, 300, Path.Direction.CW);
mPath.addCircle(300, 300, 100, Path.Direction.CW);
mPath.setFillType(Path.FillType.WINDING);
canvas.drawPath(mPath,mPaint);
}
至此,所有的Path的使用基本介绍完毕。下面我们继续我们前进的脚步,学习与Path对象息息相关的一个对象——PathMeasure。见名思意,该类的功能就是用来测量Path对象的。
PathMeasure
(1)、无参构造方法
public PathMeasure() {
mPath = null;
native_instance = native_create(0, false);
}
(2)有参构造方法
public PathMeasure(Path path, boolean forceClosed) {
// The native implementation does not copy the path, prevent it from being GC'd
mPath = path;
native_instance = native_create(path != null ? path.ni() : 0,
forceClosed);
}
(1)、public void setPath(Path path, boolean forceClosed) ,设置测量的path对象
(2)、public float getLength() ,测量path的长度
(3)、 public boolean getPosTan(float distance, float pos[], float tan[]),根据distance获取对应的点坐标
(4)、public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo),返回指定distance之间的path段。
注意:无论多复杂,PathMeasure也是将所有path中的路径看成一个直线,取位置,然后计算出对应的坐标。