前言:

通过view绘制虚实线,采用Android自带API——DashPathEffect。具体使用请参考更多的链接,这里只是讲解。

构造函数

DashPathEffect 的构造函数有两个参数:

DashPathEffect (float[] intervals, float phase)

官方文档解释如下:

The intervals array must contain an even number of entries (>=2), with the even indices specifying the "on" intervals, and the odd indices specifying the "off" intervals. phase is an offset into the intervals array (mod the sum of all of the intervals). The intervals array controls the length of the dashes. The paint's strokeWidth controls the thickness of the dashes. Note: this path effect only affects drawing with the paint's style is set to STROKE or FILL_AND_STROKE. It is ignored if the drawing is done with style == FILL.

翻译成中文如下:

间隔数组必须包含偶数个条目(大于等于2),偶数索引指定“开”间隔,而奇数索引指定“关”间隔。相位是间隔数组的偏移量(所有间隔的总和)。间隔数组控制了冲线的长度。画笔宽度宽度控制着冲线的厚度。注意:路径效果只对画笔样式为描边或填充和描边有效。如果画笔样式为填充则会忽略它。

下面通过一个示例来研究这两个参数的作用。

代码部分

  • MainActivity.java
package ivan.rich.patheffect;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns: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="ivan.rich.patheffect.MainActivity"><ivan.rich.patheffect.PathEffectViewandroid:layout_width="match_parent"android:layout_height="match_parent"/>
</LinearLayout>
  • PathEffectView.java
package ivan.rich.patheffect;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;public class PathEffectView extends View {private int mWidth;private int mHeight;private Paint mLinePaint;private Paint mPaint;private Path mPath;public PathEffectView(Context context) {this(context, null);}public PathEffectView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}private void init() {mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStrokeWidth(20);mPaint.setColor(getResources().getColor(R.color.colorPrimary));mPaint.setStyle(Paint.Style.STROKE);mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);mLinePaint.setStrokeWidth(1);mLinePaint.setStyle(Paint.Style.STROKE);mLinePaint.setColor(getResources().getColor(R.color.colorAccent));mPath = new Path();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mWidth = w;mHeight = h;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 绘制一条参考线canvas.drawLine(60, 0, 60, mHeight, mLinePaint);// 绘制第一条虚线DashPathEffect dashPathEffect1 = new DashPathEffect(new float[]{60, 60}, 0);mPaint.setPathEffect(dashPathEffect1);mPath.reset();mPath.moveTo(0, mHeight / 10);mPath.lineTo(mWidth, mHeight / 10);canvas.drawPath(mPath, mPaint);// 绘制第二条虚线DashPathEffect dashPathEffect2 = new DashPathEffect(new float[]{60, 60}, 20);mPaint.setPathEffect(dashPathEffect2);mPath.reset();mPath.moveTo(0, mHeight * 2 / 10);mPath.lineTo(mWidth, mHeight * 2 / 10);canvas.drawPath(mPath, mPaint);// 绘制第三条虚线DashPathEffect dashPathEffect3 = new DashPathEffect(new float[]{60, 60}, 40);mPaint.setPathEffect(dashPathEffect3);mPath.reset();mPath.moveTo(0, mHeight * 3 / 10);mPath.lineTo(mWidth, mHeight * 3 / 10);canvas.drawPath(mPath, mPaint);// 绘制第四条虚线DashPathEffect dashPathEffect4 = new DashPathEffect(new float[]{60, 60}, 60);mPaint.setPathEffect(dashPathEffect4);mPath.reset();mPath.moveTo(0, mHeight * 4 / 10);mPath.lineTo(mWidth, mHeight * 4 / 10);canvas.drawPath(mPath, mPaint);// 绘制第五条虚线DashPathEffect dashPathEffect5 = new DashPathEffect(new float[]{60, 60, 30, 30}, 0);mPaint.setPathEffect(dashPathEffect5);mPath.reset();mPath.moveTo(0, mHeight * 6 / 10);mPath.lineTo(mWidth, mHeight * 6 / 10);canvas.drawPath(mPath, mPaint);// 绘制第六条虚线DashPathEffect dashPathEffect6 = new DashPathEffect(new float[]{60, 30, 30, 60}, 0);mPaint.setPathEffect(dashPathEffect6);mPath.reset();mPath.moveTo(0, mHeight * 7 / 10);mPath.lineTo(mWidth, mHeight * 7 / 10);canvas.drawPath(mPath, mPaint);// 绘制第七条虚线DashPathEffect dashPathEffect7 = new DashPathEffect(new float[]{30, 60, 60, 30}, 0);mPaint.setPathEffect(dashPathEffect7);mPath.reset();mPath.moveTo(0, mHeight * 8 / 10);mPath.lineTo(mWidth, mHeight * 8 / 10);canvas.drawPath(mPath, mPaint);// 绘制第八条虚线DashPathEffect dashPathEffect8 = new DashPathEffect(new float[]{30, 30, 60, 60}, 0);mPaint.setPathEffect(dashPathEffect8);mPath.reset();mPath.moveTo(0, mHeight * 9 / 10);mPath.lineTo(mWidth, mHeight * 9 / 10);canvas.drawPath(mPath, mPaint);}
}

运行结果

参数分析

1.首先看截图上半部分的四条虚线段,四条虚线对应的DashPathEffect如下:

DashPathEffect dashPathEffect1 = new DashPathEffect(new float[]{60, 60}, 0);
DashPathEffect dashPathEffect2 = new DashPathEffect(new float[]{60, 60}, 20);
DashPathEffect dashPathEffect3 = new DashPathEffect(new float[]{60, 60}, 40);
DashPathEffect dashPathEffect4 = new DashPathEffect(new float[]{60, 60}, 60);

这四个DashPathEffect的区别在于第二个参数phase值不同,以参考线为基准可以清晰地看到phase参数的作用是将整个View向“左”移动phase。什么意思呢,左移为0:不移动;左移为20:移动20个单位长度;左移为40:移动40个单位长度。因此,左移60的时候,第四根线条相对第一根线条,左移了一个实线段。

2.然后看截图下半部分的四条虚线段,这四条虚线段对应的DashPathEffect如下:

DashPathEffect dashPathEffect5 = new DashPathEffect(new float[]{60, 60, 30, 30}, 0);
DashPathEffect dashPathEffect6 = new DashPathEffect(new float[]{60, 30, 30, 60}, 0);
DashPathEffect dashPathEffect7 = new DashPathEffect(new float[]{30, 60, 60, 30}, 0);
DashPathEffect dashPathEffect8 = new DashPathEffect(new float[]{60, 60, 40, 40, 20, 20}, 0);

从效果图可以看出间隔数组的偶数索引处数组值对应的是实线宽度,奇数索引处数组值对应的是实线之后空白线的宽度。前面已经提到过数组必须包含偶数个条目,所以“on”和“off”值是对应的。在绘制View时系统遍历当前间隔数组,依次绘制第一个“on”和第一个“off”值,第二个“on”和第二个“off"值。。。,照此类推直至绘制完所有对应的"on"和"off”值,然后按照此方法循环遍历间隔数组直至View的绘制完成。用代码概括来说就是:

for (i=0 ; i<intervals.length; i+=2) {// 实线宽度onmLineWidth = intervals[i];// 实线之间空白线宽度offmBlankSpace = intervals[i+1];
}

总结

构造函数

DashPathEffect(float intervals[], float phase)

参数含义

  • intervals: 控制实线和实线之后空白线的宽度(数组长度必须为偶数)
  • phase: 将View向”左“偏移phase

用法

Paint.setPathEffect(DashPathEffect dashPathEffect);

Android 虚线实现绘制 - DashPathEffect相关推荐

  1. Android Drawable (可绘制图像)

    Drawable (可绘制图像) 本文由 Luzhuo 编写,转发请保留该信息. 原文: https://blog.csdn.net/Rozol/article/details/87100169 Dr ...

  2. android 继承类图,Android Studio中绘制UML类图介绍

    Android Studio中绘制UML类图介绍 Android Studio中绘制UML类图介绍 动机 最近开始阅读项目源码,从其中一个模块开始看,奈何大项目中的一个模块,对于萌新而言,也太过于复杂 ...

  3. Android之View绘制流程源码分析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于稍有自定义View经验的安卓开发者来说,onMeasure,onLayout,onDraw这三个方法都不会陌生,起码多少都有所接触吧. 在安卓中 ...

  4. android WPS如何绘制垂直和水平的直线

    今天,简单讲讲android 里如何使用WPS绘制直线时使直线可以水平和垂直. 记得昨天讲了如何使用WPS插入图形,其中其实就有直线可以绘制.但是自己在绘制流程图时,发在很难绘制垂直和水平的线条,所以 ...

  5. android圆形头像 demo,Android图像处理之绘制圆形头像

    在Android中,绘制圆形和绘制图片都是很容易的事情,但是绘制圆形图片就有点难倒人了.以前为了偷懒就直接去github上找一个开源项目,后来才发现绘制圆形图片其实也是很简单的事.绘制圆形图片也需要两 ...

  6. Android View的绘制机制流程深入详解(一)

    本系列文章主要着重深入介绍Android View的绘制机制及流程,第一篇主要介绍并分析LayoutInflater的原理, 从而理解setContentView的加载原理.对于LayoutInfla ...

  7. Android View的绘制机制流程深入详解(二)

    本系列文章主要着重深入介绍Android View的绘制机制及流程,第二篇主要介绍并分析Android视图的绘制的原理和流程.主要从 onMeasure().onLayout()和onDraw()这三 ...

  8. android小球移动代码,Android中如何绘制一个跟随手指移动的小球

    Android中如何绘制一个跟随手指移动的小球 发布时间:2020-11-07 16:22:43 来源:亿速云 阅读:82 作者:Leah 本篇文章为大家展示了Android中如何绘制一个跟随手指移动 ...

  9. Android中View绘制各种状态的背景图片原理深入分析以及StateListDrawable使用

    /* Call this to force a view to update its drawable state. This will cause drawableStateChanged to b ...

最新文章

  1. linux 命令行 过滤,利用linux命令行工具进行文本行过滤
  2. 第14件事 分析竞争对手的方法
  3. WinRAR 命令行简体中文说明
  4. 成年人改变生活的方式,都是从它开始
  5. C#网络编程之Http请求
  6. 使用WebBrowser自动登录阿里妈妈网站
  7. c++笔试题整理(二)
  8. dyve/django-bootstrap-toolkit
  9. 关注物业公司信息化建设
  10. Hexo博客进阶:为 Next 主题添加 Waline 评论系统
  11. linux系统小红帽和ubuntu,Thinkpad trackpoint小红帽和中间键功能的实现。
  12. Java时间改变事件,我如何计算java中事件的经过时间?
  13. OpenJudge 百练 2787 算24
  14. SpringBoot常用标签的理解
  15. linux下载测序数据,高速下载测序数据(SRA,Fastq等)
  16. SVM学习总结(三)SMO算法流程图及注释源码
  17. 基于SSM框架的借阅图书管理系统
  18. html5 在线 ppt 制作软件,HTML5 幻灯片相册制作工具(HTML5 Slideshow Maker)
  19. 【机器学习】隐马尔可夫模型
  20. 开发工作中常用网站宝典(建议收藏!!!)

热门文章

  1. linux php 如何停止,如何关闭linux
  2. OPENCV标定外参
  3. IDNO简单生成方法
  4. caffe---ubuntu1604下anaconda2.5的尝试----失败,建议使用系统的python系统,避免各种各样的陷阱...
  5. 谁动了我的主机? 之活用History命令|Linux安全运维
  6. Ubuntu Nginx uwsgi django 初试
  7. linux常见命令汇总
  8. python Day1作业:用户三次登陆锁定
  9. c#接口和抽象类对比学习
  10. 【Quartz】Quartz