Path作为Android中一种相对复杂的绘图方式,官方文档中的有些解释并不是很好理解,这里作一个相对全面一些的总结,供日后查看,也分享给大家,共同进步。

1.基本绘图方法

  1. addArc(RectF oval, float startAngle, float sweepAngle)
    绘制弧线,配合Paint的Style可以实现不同的填充效果
  2. addCircle(float x, float y, float radius, Path.Direction dir)
    绘制圆形,其中第dir参数用来指定绘制时是顺时针还是逆时针
  3. addOval(RectF oval, Path.Direction dir)
    绘制椭圆形,其中 oval作为椭圆的外切矩形区域
  4. addRect(RectF rect, Path.Direction dir)
    绘制矩形
  5. addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
    绘制圆角矩形
  6. lineTo(float x, float y)
    绘制直线
  7. addPath(Path src)
    添加一个新的Path到当前Path
  8. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
    addArc方法相似,但也有区别,下文细述。
  9. quadTo(float x1, float y1, float x2, float y2)
    绘制二次贝塞尔曲线,其中 (x1,y1)为控制点,(x2,y2)为终点
  10. cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
    绘制三次贝塞尔曲线,其中(x1,y1),(x2,y2)为控制点,(x3,y3)为终点

2.rXXX方法

上面的lineTo,MoveTo,QuadTo,CubicTo方法都有与之对应的rXXX方法:

  1. rLineTo(float dx, float dy)
  2. rMoveTo(float dx, float dy)
  3. rQuadTo(float dx1, float dy1, float dx2, float dy2)
  4. rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

这些方法与之对应的原方法相比,惟一的区别在于:r方法是基于当前绘制开始点的offest,比如当前paint位于 (100,100)处,则使用rLineTo(100,100)方法绘制出来的直线是从(100,100)到(200,200)的一条直接,由此可见rXXX方法方便用来基于之前的绘制作连续绘制。

3.Path.op方法

1
2
3
4
//原型
op(Path path, Path.Op op)
//eg
path1.op(path2,Path.Op.DIFFERENCE);

此方法用于对两个Path对象做相应的运算组合(combine),具体的说是根据不同的op参数及path2参数来影响path1对象,有点类似于数学上的集合运算。请看下面的例子:

1
2
3
4
5
6
Path path1 = new Path();
path1.addCircle(150, 150, 100, Path.Direction.CW);
Path path2 = new Path();
path2.addCircle(200, 200, 100, Path.Direction.CW);
path1.op(path2, Path.Op.DIFFERENCE);
canvas.drawPath(path1, paint1);

效果如下:

通过不断修改path1.op的第二个参数依次可以得到如下效果:

Path.Op.INTERSECT效果:

Path.Op.UNION效果:

Path.Op.REVERSE_DIFFERENCE效果:

Path.Op.XOR效果:

总结:
  1. Path.Op.DIFFERENCE 减去path1中path1与path2都存在的部分;
    path1 = (path1 - path1 ∩ path2)
  2. Path.Op.INTERSECT 保留path1与path2共同的部分;
    path1 = path1 ∩ path2
  3. Path.Op.UNION 取path1与path2的并集;
    path1 = path1 ∪ path2
  4. Path.Op.REVERSE_DIFFERENCE 与DIFFERENCE刚好相反;
    path1 = path2 - (path1 ∩ path2)
  5. Path.Op.XOR 与INTERSECT刚好相反;
    path1 = (path1 ∪ path2) - (path1 ∩ path2)

4.setFillType

设置path的填充模式.网上关于path的FillType的介绍很少,实际上在官方ApiDemos里就有个很好的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* Created by ghui on 10/25/15.
*/
public class PathFillTypeView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPath; public PathFillTypeView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true); mPath = new Path();
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
mPath.addCircle(120, 120, 45, Path.Direction.CCW);
} private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
Paint paint) {
canvas.save();
canvas.translate(x, y);
canvas.clipRect(0, 0, 160, 160);
canvas.drawColor(Color.WHITE);
mPath.setFillType(ft);
canvas.drawPath(mPath, paint);
canvas.restore();
} @Override
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
paint.setColor(Color.RED);
canvas.drawColor(0xFFCCCCCC);
canvas.translate(20, 20);
paint.setAntiAlias(true);
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
showPath(canvas, 160 * 2, 0, Path.FillType.EVEN_ODD, paint);
showPath(canvas, 0, 160 * 2, Path.FillType.INVERSE_WINDING, paint);
showPath(canvas, 160 * 2, 160 * 2, Path.FillType.INVERSE_EVEN_ODD, paint);
}
}

效果如下:

(上面的例子在官方ApiDemo的基础上做了适当的修改)

总结:

所谓填充指的就是填充内部,setFillType就是用来界定哪里算内部的算法。在计算机图形学中界定一个点是不是在多边形内部有两种算法:

  1. 非零环绕数规则(Nonzero-rule)
  2. 奇偶规则(Even–odd rule)

关于这两种算法这里不作详细介绍,具体可以参考上面的维基链接,或者这篇中文资料(注意看评论区)

5.易混淆的方法

1. addArc 与 arcTo

前者指定在某处画一条弧线,仅此而已,不会受当前paint的位置所影响。而arcTo方法有两种形式:

  1. arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
  2. arcTo(RectF oval, float startAngle, float sweepAngle)

    对于第一种形式的方法,若forceMoveTo参数为false,则与第二种形式的方法没区别,绘制成的最终图形会受到落笔点的影响;
    若forceMoveTo参数值为true,则绘制效果与addArc方法没有区别。

1
2
3
4
5
//代码1
Path path = new Path();
path.moveTo(100, 100);
path.addArc(200, 200, 400, 400, 0, 150);
canvas.drawPath(path, paint);

代码1效果如下图:

1
2
3
4
5
//代码2
Path path = new Path();
path.moveTo(100, 100);
path.arcTo(200, 200, 400, 400, 0, 150, false);
canvas.drawPath(path,paint);

代码2效果如下图:

若将代码2中的arcTo方法的参数修改为true则绘制的效果与代码1相同。

2. reset 与 rewind

reset清除path上的内容,重置path到 path = new Path()的初始状态。
rewind清除path上的内容,但会保留path上相关的数据结构,以高效的复用。
Detail

其它方法

  1. moveTo(float x,float y)
    移动画笔到 (x,y) 处
  2. offset(float dx, float dy)
    平移当前path,在此path上绘制的任何图形都会受到影响
  3. close()
    闭合当前路径 (系统会自动从起点到终点绘制一条直线,使当前路径闭合)
  4. reset()
    重置path,但不会重置fill-type设置
  5. rewind()
    重置path,但会保留内部数据结构
  6. set(Path src)
    设置新的Path到当前对象
  7. setLastPoint(float x,float y)
    设置当前path的终点
  8. transform(Matrix matrix)
    矩阵变换
转自:http://ghui.me/post/2015/11/android-graphics-path/

Android使用绘图Path总结的更多相关文章

  1. 【转】Android Canvas绘图详解(图文)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...

  2. Android 2D绘图初步

    Android是通过graphics类来显示2D图形的.其中graphics中包括了Canvas.Paint.Color.Bitmap等类.graphics具有绘制点.线.颜色.2D几何图形.图像处理 ...

  3. Android开发——绘图基础

    前言: Android中绘图基本三个类,分别是Paint(画笔),Path(路径),Canvas(画布),这三个也是自定义View经常会使用到的类 个人理解,Canvas画布这个翻译其实不太好,这个类 ...

  4. Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法

    http://www.cnblogs.com/SkyD/archive/2010/11/08/1871423.html Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法 Surfa ...

  5. cocos2dx在Eclipse下编译报错:Cannot find module with tag 'CocosDenshion/android' in import path

    在Eclipse下编译cocos2dx项目,报错如下: Android NDK: jni/Android.mk: Cannot find module with tag 'CocosDenshion/ ...

  6. Android 画布绘图

    我们已经介绍了Canvas,在那里,已经学习了如何创建自己的View.在第7章中也使用了Canvas来为MapView标注覆盖. 画布(Canvas)是图形编程中一个很普通的概念,通常由三个基本的绘图 ...

  7. Android Drawable绘图学习笔记(转)

    如何获取 res 中的资源 数据包package:android.content.res 主要类:Resources Android SDK中的简介:Class for accessing an ap ...

  8. Android Canvas 绘图

    画布(Canvas)是图形编程中一个很普通的概念,通常由三个基本的绘图组件组成:       Canvas  提供了绘图方法,可以向底层的位图绘制基本图形.       Paint  也称为" ...

  9. android xfermode绘图

    1.fermode:是来自 transfer-modes,在画笔中设置xfermode后,画笔在使用的时候就会应用设置的像素转换模式.就类似于ps中的选取功能,留下的选取是从原选区中去除还是合并,取交 ...

随机推荐

  1. 初学Ajax(三)

    $.ajax() $.ajax()是所有ajax方法中最底层的方法,所有其他方法都是基于$.ajax()方法的封装.这个方法只有一个参数,传递一个各个功能键值对的对象. $.ajax()方法对象参数表 ...

  2. 如何开启Centos6.4系统的SSH服务

    无论是Centos6.4系统的虚拟电脑还是服务器,始终感觉直接在命令行中操作不方便:比如全选.复制.粘贴.翻页等等.比如服务器就需要在机房给服务器接上显示器.键盘才操作感觉更麻烦.所以就可借助SSH( ...

  3. CentOS安装Chrome

    问题 在CentOS安装Chrome会遇到 libstdc++.so.6(GLIBCXX_3.4.15)(64bit) 依赖失败的问题, 即使下载了最新的libstdc++.so.6(包含GLIBCX ...

  4. java_String和StringBuffer区别分析

    JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据.这个String类提供了数值不可改变的字符串.而这个StringBuffer类提供 ...

  5. Spring框架学习之第8节

    <bean id=”foo” class=”…Foo”> <property name=”属性”> <!—第一方法引用--> <ref bean=”bean对 ...

  6. hive-学习笔记

    1.hive模糊搜索表  show tables like '*name*'; 2.查看表结构信息  desc formatted table_name;  desc table_name; 3.查看 ...

  7. 《jQuery风暴》第2章 必须知道的JavaScript知识

    第2章 必须知道的JavaScript知识 JavaScript是jQuery应用的基础,掌握JavaScript这门语言是使用jQuery的基础条件.本章不会全面细致的讲解JavaScript的全部 ...

  8. 跨平台 c 开发库 tbox v1.6.0,支持跨平台协程

    http://www.oschina.net/news/78582/tbox-v-1-6-0

  9. CentOS启动和停止服务详解

    服务简介Linux 系统服务是在Linux启 动时自动加载,并在Linux退出时自动停止的系统任务.在Linux 启动过程中,我们可以看得很多“starting … ”提示信息,该信息表示正在启动系统 ...

  10. Centos下修改启动项和网络配置

    1.Centos默认是从图形界面启动,需要较多的资源,为了节省资源可以从命令行启动.修改方法如下: /etc/inittab文件,把 代码: id:5:initdefault:这一行,修改成 代码: ...