我的编程空间,编程开发者的网络收藏夹
学习永远不晚

自定义视图View绘图基础之Path的使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

自定义视图View绘图基础之Path的使用

使用Path绘制线

path类是一个非常有用的类,他可以预先在view上讲N个点连成一条“路径”,然后调用Canvas的drawPath(path,paint)即可沿着路径绘制图形,并且Android还为路径提供了pathEffect来绘制效果,pathEffect包含了如下子类
-ComposePathEffect
-ComnerPathEffect
-DashPathEffect
-DiscretePathEffect
-PathDashPathEffect
-SunPathEffect

一、我们这里绘制了7条线来分别介绍上面的几种子类都有什么用

代码如下

运行效果

这里写图片描述

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;



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 = new Path();
        path.moveTo(0, 0);
//--------------------------第三步---------------------------
          
        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;

// ---------------------------------------------------
         
        effects[1] = new CornerPathEffect(10);

// ---------------------------------------------------
        
        effects[2] = new DiscretePathEffect(1.0f, 5.0f);

// ---------------------------------------------------

        
        effects[3] = new DashPathEffect(new float[] { 20, 10, 5, 10 },phase);

// ---------------------------------------------------

        
        Path p = new Path();
        p.addRect(0, 0, 8, 8, Path.Direction.CCW);
        effects[4] = new PathDashPathEffect(p, 12, phase,PathDashPathEffect.Style.ROTATE);

// ---------------------------------------------------
        
        // 初始化ComposePathEffect
        effects[5] = new ComposePathEffect(effects[2], effects[4]);

// ---------------------------------------------------
        
        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值,形成动画效果

// ---------------------------------------------------
        
        phase += 1;
        invalidate();
    }
}

二、不难看出其中每条线的属性和样式不一样,我在上面有 了很详细的讲解。

这里就不在介绍没个子类的属性了,代码很简单,步骤如下:

1、创建一个类继承view

2、定义一个线集合,用来添加我们绘制的7跳线,通过一个for循环依次绘制

3、上面代码中,在注释中前四步是准备工作,创建画笔、设置画布颜色、设定转折点的数量及每条线的颜色

4、引用子类对象 ,来为每条线添加不同的属性。

5、进行绘制,并且设置偏移量加1,并且设置重绘方法,实现一个动画效果

代码结构视图

这里写图片描述

三、xxxTo()方法绘制(本章延伸知识)

一、直线绘制

  • 1.1 lineTo(float x, float y)
@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);
    }

这里写图片描述

  • 多次调用lineTo方法来绘制
    @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);
    }

这里写图片描述

1.2 moveTo(float x, float y) +close()方法闭合曲线


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

这里写图片描述

二、画贝赛尔曲线

  • quadTo(float x1, float y1, float x2, float y2)
 @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);
    }

这里写图片描述

这里写图片描述

  • 2.3 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.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);
    }

这里写图片描述

这里写图片描述

三、画弧线

  • arcTo (RectF oval, float startAngle, float sweepAngle) 是一个画弧线的方法,其实说白了就是从圆或椭圆上截取一部分而已。
 @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);
    }

这里写图片描述

  • arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) 它会强制起点为绘制的起始点,而不是画布的左上角。

我们来看看效果:

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

这里写图片描述

四、Path中除了上面介绍的几个XXXTo方法外还有一套rXXXTo方法:

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)

五、rXXXTo()方法和XXXTo()的区别

例如: 起点(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);
    }

这里写图片描述

这里的move和lineTo的坐标都是对于画布左上角(0,0)来说的,是一个绝对坐标。而我们换为mPath.rLineTo(200, 200); 后呢?

这里写图片描述

是不是感觉线段长了很多,因为这里的(200,200)是相对于开始点(100,100)来说的,是相对坐标。如果换算成绝对坐标就是绘制一条(100,100)到(300,300)之间的线段。

其实,这个前缀“r”也就是relative(相对)的简写!

六、addXXX方法

XXXTo方法可以连接Path中的曲线,而Path提供的另一系列addXXX方法则可以让我们直接往Path中添加一些曲线,比如

  • addArc(RectF oval, float startAngle, float sweepAngle) : 它允许我们将一段弧形添加至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);
    }

这里写图片描述

如图和代码所示,虽然我们先绘制了由[100,100]到[200,200]的线段,但是在我们往Path中添加了一条弧线后该弧线并没与线段连接。

除了addArc,Path还提供了一系列的add方法:

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)

这些方法和addArc有很明显的区别,就是多了一个Path.Direction参数,其他呢都大同小异,除此之外不知道大家还发现没有,addArc是往Path中添加一段弧,说白了就是一条开放的曲线,而上述几种方法都是一个具体的图形,或者说是一条闭合的曲线,Path.Direction的意思就是标识这些闭合曲线的闭合方向。Path.Direction只有两个常量值CCW和CW分别表示逆时针方向闭合和顺时针方向闭合

例如顺时针方向闭合

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

这里写图片描述

如果我们换作:mPath.addOval(oval, Path.Direction.CCW);

  • 逆时针封闭

这里写图片描述

到此这篇关于自定义视图View绘图基础之Path的使用的文章就介绍到这了,更多相关自定义视图Path使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

自定义视图View绘图基础之Path的使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

自定义视图View绘图基础之Path的使用

这篇文章主要介绍了自定义视图View绘图基础之Path的使用,path类是一个非常有用的类,他可以预先在view上讲N个点连成一条“路径”,然后调用Canvas的drawPath(path,paint)即可沿着路径绘制图形,需要的朋友可以参考下
2023-05-14

自定义view视图之Canvas+Paint图形绘制

这篇文章主要介绍了自定义view视图之Canvas+Paint图形绘制,我们开发自定义view的时候,就要绘制自己心仪的图形,这个时候我们就要能够熟练的运用我们的绘图知识,需要的朋友可以参考下
2023-05-14

自定义视图view的折线图使用讲解

这篇文章主要介绍了自定义视图view的折线图使用讲解,前面几章讲解了绘图的一些基本用法,本章就来看看折线图吧,需要的朋友可以参考下
2023-05-14

自定义视图view的折线图怎么使用

这篇文章主要讲解了“自定义视图view的折线图怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“自定义视图view的折线图怎么使用”吧!绘制折线图预览图绘制这个折线图需要都需要哪些步骤?
2023-07-05

Android开发之自定义View(视图)用法详解

本文实例讲述了Android开发之自定义View(视图)用法。分享给大家供大家参考,具体如下: View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。在游戏开发
2022-06-06

Android自定义View基础开发之图片加载进度条

学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看。 按照惯例,先看效果图,再决定要不要往下看:既然看到这里了,应该是想了解这个图片加载进度条了,我们先看具体用法,再看自定义View的实
2022-06-06

图文详解自定义View视图的属性及引用

这篇文章主要介绍了图文详解自定义View视图的属性及引用,由于Android自带的视图无法满足自己需求,又或者美观度不够自己的要求,我们就要自来亲自设计自己的视图,需要的朋友可以参考下
2023-05-14

怎么自定义View视图的属性及引用

今天小编给大家分享一下怎么自定义View视图的属性及引用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、创建一个类,继承V
2023-07-05

自定义视图view使用Canvas实现手写板和涂鸦功能

这篇文章主要介绍了自定义视图view使用Canvas实现手写板和涂鸦功能,这里直接上代码,里面有详细讲解和注释,需要的朋友可以参考下
2023-05-14

怎么自定义视图view使用Canvas实现手写板和涂鸦功能

本文小编为大家详细介绍“怎么自定义视图view使用Canvas实现手写板和涂鸦功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么自定义视图view使用Canvas实现手写板和涂鸦功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入
2023-07-05

Xamarin XAML语言中如何使用ContentView视图作为自定义视图的父类

这篇文章主要介绍Xamarin XAML语言中如何使用ContentView视图作为自定义视图的父类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!自定义视图的父类:ContentView视图可以作为自定义视图的父类。
2023-06-04

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录