自定义View学习笔记(2)->Path


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

public class CustomView extends View {

    private Paint paint;

    public CustomView(Context context) {
        super(context);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(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

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.snow.viewfirst.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

    <com.snow.viewfirst.CustomView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.snow.viewfirst.CustomView>
</RelativeLayout>

下面进入正题,看一下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) {
    super.onDraw(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);
}


效果图



利用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);

}


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);

}

后面的我就没有调试了,有兴趣的同学可以自己试试。

本文转载自:http://blog.csdn.net/leejizhou/article/details/51565057



























































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值