Android 2D绘图解析之 Path

原创 2016年06月05日 11:07:36

*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

原创文章,转载请注明 ( 来自:http://blog.csdn.net/leejizhou/article/details/51565057 李济洲的博客 )

上一篇文章 http://blog.csdn.net/leejizhou/article/details/51524948 介绍了Android绘图中的Canvas,Paint两个API并简单实现了一些绘图效果,例如圆形,矩形,弧线等等,这些都是Android预置好的绘图方法,但是如果我们想要绘制一些复杂的图形怎么办呢?例如绘制一个三角形,N变形,非规则图形呢?好在Android给我们提供了Canvas的drawPath(Path path, Paint paint)方法,这个Path是什么呢?Path中文是路径的意思,我们可以通过在View上预设几个点形成一个路径,然后通过drawPath方法沿着路径进行绘制,这篇主要介绍Path的一些常用方法。

同样Android进行图形绘制的前提是需要继承自View,然后重写它的onDraw(Canvas canvas) 方法即可。

首先我们新建一个类继承自View,重写onDraw方法,并设置了绘图风格。

package com.lijizhou.pathdemo;
public class CustomView extends View {

    private Paint paint;
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //绘制风格
        setViewPaint();
    }


    public void setViewPaint(){
        //绘制风格
        paint=new Paint();
        //去锯齿
        paint.setAntiAlias(true);
        //设置绘制颜色
        paint.setColor(getResources().getColor(android.R.color.holo_blue_light));
        //为了方便看Path的路径效果
        //设置绘制风格为空心
        paint.setStyle(Paint.Style.STROKE);
        //设置空心边框的宽度
        paint.setStrokeWidth(10);
    }
}

然后在Layout中添加此View

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lijizhou.pathdemo.MainActivity">

    <com.lijizhou.pathdemo.CustomView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

OK 基础的框架就搭成了,我们进行的绘制都在onDraw方法里面。

说个题外话,对于上一篇文章里面进行绘制的时候方法里面传入了一些300,500之类的数值,可能有些朋友不是特别明白,所以下面我用画图工具画了一张图,你或许就能明白了,当然这是默认情况下的坐标系,当你移动canvas时候就不是下面这样的了。

这里写图片描述

下面进入正题,看一下Path主要有哪些方法可以使用

  • moveTo:设置路径起始点
  • lineTo:添加直线到路径
  • arcTo:添加弧线到路径
  • rMoveTo:设置路径起始点,参数相对于当前绘制点
  • rLineTo:添加直线到路径,参数相对于当前绘制点
  • rArcTo:添加弧线到路径,参数相对于当前绘制点
  • close:闭合路径
  • addArc:添加一个圆弧到路径
  • addCircle:添加一个圆到路径
  • addOval:添加一个椭圆到路径
  • addRect:添加一个矩形到路径
  • reset:重置路径
  • offset:对路径进行偏移
  • op:两个路径组合操作

更多方法参考:https://developer.android.com/reference/android/graphics/Path.html(科学上网)

利用moveTo,lineTo,close方法绘制各种直线图形:

moveTo(float x, float y):移动Path的绘制起点
x:View的x坐标,y:View的y坐标

lineTo(float x, float y) :构建从绘制的上一个点到xy的一条直线
x:View的x坐标,y:View的y坐标

close():闭合路径,对Path终点与起点进行直线连接

示例代码:

   @Override
    protected void onDraw(Canvas canvas) {
        //设置绘制风格
        setViewPaint();
        //构建Path路径
        Path path=new Path();
        //设置path的起点位置
        path.moveTo(200,200);
        //path路径连接至某点
        path.lineTo(100,400);
        path.lineTo(300,400);
        //path路径的最后一个点与起点连接,如果不写这句三角形就会变成LEXUS的车标了:)
        path.close();
        //绘制三角形
        canvas.drawPath(path,paint);


        //如果这里不设置moveTo那么path将沿着上面那个三角形路径最后一点进行继续绘制
        path.moveTo(100,800);
        path.lineTo(200,500);
        path.lineTo(300,800);
        path.lineTo(400,500);
        path.lineTo(500,800);
        //绘制M形
        canvas.drawPath(path,paint);
    }

运行效果:

这里写图片描述

利用arcTo绘制各种弧线图形

arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)构建一个弧线到Path
left,top,right,bottom:因为是弧线所以要构建一个矩形区域
left:矩形left的x坐标
top:矩形top的y坐标
right:矩形right的x坐标
bottom:矩形bottom的y坐标
startAngle:圆弧起始角度,单位为度 (0~360)
sweepAngle:圆弧扫过的角度,顺时针方向,单位为度 (0~360)
forceMoveTo:false代表弧线起点与上个绘制的最后一个点连接,true代表不连接。

可能会有朋友问画弧线需要构建矩形是什么意思?设置圆弧起始角度那么0度在哪呢?再用画图工具画一下

这里写图片描述

示例代码:

   @Override
    protected void onDraw(Canvas canvas) {
        //设置绘制风格
        setViewPaint();

        Path path=new Path();
        //添加各种角度弧线
        path.arcTo(100,100,300,300,0,90,true);

        path.arcTo(100,400,300,600,0,180,true);

        path.arcTo(100,700,300,900,270,180,true);

        //最后一个参数填false,看效果
        path.arcTo(100,1000,300,1200,0,180,false);
        //绘制
        canvas.drawPath(path,paint);

    }

运行效果:可以看到第四个弧线起始点与第三个弧线终点自动连接上了,因为第四个弧线forceMoveTo我们设置了false。

这里写图片描述

Path同样也给我们封装好了一些路径效果,例如圆形,矩形等等,跟canvas.drawXX比较类似,这里就简单介绍下

addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle) 添加弧线到路径
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) 添加矩形到路径
上面的Path.Direction dir参数用来指定绘制时是顺时针还是逆时针,Path.Direction.CCW和Path.Direction.CW分别代表逆时针和顺时针,顺时针和逆时针主要的作用在于不同的时针方向也就决定了不同的路径起始点和终点,其他的参数跟canvas.drawXX是一样的,上一篇已经介绍过了,这里就不做具体介绍了。

示例代码:

 @Override
    protected void onDraw(Canvas canvas) {
        //设置绘制风格
        setViewPaint();
        //构建path
        Path path=new Path();
        //添加弧形到path
        path.addArc(100,100,300,300,0,270);
        //添加圆形到path
        path.addCircle(200,500,100,Path.Direction.CCW);
        //添加矩形到path
        path.addRect(100,700,300,800, Path.Direction.CW);
        //添加椭圆到path
        path.addOval(100,900,300,1000, Path.Direction.CCW);
        //绘制path
        canvas.drawPath(path,paint);

    }

运行效果:

这里写图片描述

再介绍一个比较好用的op(Path path, Path.Op op) 方法,用于将两个Path路径进行组合之后的效果设置,靠op方法可以快速组合生成一些复杂的图形效果,例如月牙形
Path.Op有如下几种参数
Path.Op.DIFFERENCE:减去Path2后Path1剩下的部分
Path.Op.INTERSECT:保留Path1与Path2共同的部分
Path.Op.REVERSE_DIFFERENCE:减去Path1后Path2剩下的部分
Path.Op.UNION:保留全部Path1和Path2
Path.Op.XOR:包含Path1与Path2但不包括两者相交的部分

可能看上面的文字解释有点绕口,具体效果还是动手实践下吧,我们绘制两个圆形并让它们位置相交。

代码示例:

    @Override
    protected void onDraw(Canvas canvas) {
        //设置绘制风格
        setViewPaint();
        //设置填充风格,方便观察效果
        paint.setStyle(Paint.Style.FILL);
        //构建path
        Path path=new Path();
        path.addCircle(150, 150, 100, Path.Direction.CW);
        Path path2 = new Path();
        path2.addCircle(300, 150, 100, Path.Direction.CW);
        path.op(path2,Path.Op.UNION);
        //Path.Op.UNION
        canvas.drawPath(path,paint);

        //清除路径
        path.reset();
        path2.reset();
        path.addCircle(150, 400, 100, Path.Direction.CW);
        path2.addCircle(300, 400, 100, Path.Direction.CW);
        path.op(path2,Path.Op.REVERSE_DIFFERENCE);
        //Path.Op.REVERSE_DIFFERENCE
        canvas.drawPath(path,paint);

        //清除路径
        path.reset();
        path2.reset();
        path.addCircle(150, 650, 100, Path.Direction.CW);
        path2.addCircle(300, 650, 100, Path.Direction.CW);
        path.op(path2,Path.Op.INTERSECT);
        //Path.Op.INTERSECT
        canvas.drawPath(path,paint);

        //清除路径
        path.reset();
        path2.reset();
        path.addCircle(150, 900, 100, Path.Direction.CW);
        path2.addCircle(300, 900, 100, Path.Direction.CW);
        path.op(path2,Path.Op.DIFFERENCE);
        //Path.Op.DIFFERENCE
        canvas.drawPath(path,paint);

        //清除路径
        path.reset();
        path2.reset();
        path.addCircle(150, 1150, 100, Path.Direction.CW);
        path2.addCircle(300, 1150, 100, Path.Direction.CW);
        path.op(path2,Path.Op.XOR);
        //Path.Op.XOR
        canvas.drawPath(path,paint);

    }

运行效果

这里写图片描述

Ok,一些Path常用的方法就暂时介绍到这,通过上一篇介绍的Canvas和这篇的Path,差不多就能应对大多情况下的绘制效果了,主要还得靠大家亲自动手实践,欢迎大家在下方留言,也可以点击右上角的关注:)

版权声明:本文为博主原创文章,转载请注明来源。

Android-2D绘图

概述Android中使用图形处理引擎,2D部分是android SDK内部自己提供,3D部分是用Open GL ES 1.0大部分2D使用的api都在android.graphics和android....
  • yangshangwei
  • yangshangwei
  • 2016年04月10日 23:55
  • 3992

Android 2D绘图解析之 Canvas,Paint

【Android 2D绘图解析】系列文章将全面介绍Android绘图相关,这是第一篇,简单介绍下如何利用Android API进行一些简单图形的绘制,绘图的前提是需要继承自View,然后重写它的onD...
  • leejizhou
  • leejizhou
  • 2016年05月30日 08:44
  • 10007

Android Path, Region, Paint, Canvas API篇

Android,Path,Region,Paint,Canvas API介绍。方便查阅。
  • wuyuxing24
  • wuyuxing24
  • 2016年07月02日 18:49
  • 5311

Android开发之Path类使用详解,自绘各种各样的图形!

玩过自定义View的小伙伴都知道,在View的绘制过程中,有一个类叫做Path,Path可以帮助我们实现很多自定义形状的View,特别是配合xfermode属性来使用的时候。OK,那我们今天就来看看P...
  • u012702547
  • u012702547
  • 2016年09月10日 17:54
  • 4011

android canvas\paint\path简单使用(自定义view必学)

  • 2016年04月01日 10:29
  • 6.24MB
  • 下载

Android与HTML+JS交互入门

在Android开发中,越来越多的商业项目使用了Android原生控件与WebView进行混合开发,当然不仅仅就是显示一个WebView那么简单,有时候还需要本地Java代码与HTML中的javasc...
  • leejizhou
  • leejizhou
  • 2016年03月15日 13:01
  • 38117

Android 2D绘图解析之 Path

上一篇文章介绍了Android绘图中的Canvas,Paint两个API并简单实现了一些绘图效果,例如圆形,矩形,弧线等等,这些都是Android预置好的绘图方法,但是如果我们想要绘制一些复杂的图形怎...
  • leejizhou
  • leejizhou
  • 2016年06月05日 11:07
  • 9969

【Android】2D绘图解析之 Path

http://blog.csdn.net/leejizhou/article/details/51565057 *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ...
  • Linh47
  • Linh47
  • 2016年09月01日 11:37
  • 303

Android系统下2D绘图性能提升的一些方法

作者 Zhenpu.Zhang 笔者近期开发了一款绘图类应用,其中在绘图性能提升效率方面遇到一些问题,经过咨询高手和查找前人经验,积攒了一些小小的经验,特地写下,希望能给同样有需要的程序猿一些启发...
  • maetelibom
  • maetelibom
  • 2017年01月23日 14:24
  • 1170

Android 画布绘图

我们已经介绍了Canvas,在那里,已经学习了如何创建自己的View。在第7章中也使用了Canvas来为MapView标注覆盖。 画布(Canvas)是图形编程中一个很普通的概念,通常由三个基本...
  • sd19871122
  • sd19871122
  • 2015年05月26日 17:02
  • 374
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 2D绘图解析之 Path
举报原因:
原因补充:

(最多只允许输入30个字)