转自:https://blog.csdn.net/cquwentao/article/details/51374994

概述

paint的基本绘制方法已经在前面的基本图形绘制中讲解了,这里做的是进阶讲解,讲解paint的一些进阶方法。例如:setStrokeCap,setStrokeJoin,setPathEffect等。

1. setStrokeCap(Paint.Cap cap)

cap是帽子的意思,这里的意思是设置线帽子,什么是线帽呢,就是一个线段结束后的额外部分。先来看一张图:

这里明显看出第二和第三段线段比第一段要长,这是因为设置的线帽不同导致的。

他们传入的参数分别是:

BUTT    (0),//无线帽
ROUND (1),//圆形线帽
SQUARE (2);//方形线帽
  • 1
  • 2
  • 3

代码如下:

Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(50); paint.setStrokeCap(Paint.Cap.BUTT);
canvas.drawLine(100, 100, 800, 100, paint); paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(100, 300, 800, 300, paint); paint.setStrokeCap(Paint.Cap.SQUARE);
canvas.drawLine(100, 500, 800, 500, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

代码比较好理解,不再讲解。

2.setStrokeJoin(Paint.Join join)

从join处可以知道,这里设置的是线段的连接处的样式,那么Join有哪些呢,如下:

MITER   (0),//锐角连接
ROUND (1),//圆弧连接
BEVEL (2);//斜接(把锐角替换成斜边)
  • 1
  • 2
  • 3

看一张图:

3个线段所代表的意义和上面的列举的参数顺序相同。可以清晰看出区别。

代码如下:

Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLUE);
paint.setStrokeWidth(50); Path path = new Path(); path.moveTo(100, 100);
path.rLineTo(800, 0);
path.rLineTo(0, 200);
paint.setStrokeJoin(Paint.Join.MITER);
canvas.drawPath(path, paint); paint.setStrokeJoin(Paint.Join.ROUND);
path.moveTo(100, 500);
path.rLineTo(800, 0);
path.rLineTo(0, 200);
canvas.drawPath(path, paint); paint.setStrokeJoin(Paint.Join.BEVEL);
path.moveTo(100, 1000);
path.rLineTo(800, 0);
path.rLineTo(0, 200);
canvas.drawPath(path, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

3. setPathEffect(PathEffect effect)

effect代表效果,这里明显是要设置路径的效果。那么我们先看看PathEffect有哪些子类呢

如图,子类有如上6种,那么逐个来解析他们对绘制的影响。

(1)CornerPathEffect

从名字可以看出,这个类主要作用于拐角,我们使用并看一下效果图:

下面的线条使用了这个效果,上面的是原始效果,可以看到,线条拐角处被处理成了圆弧。看下代码:

path.moveTo(100, 100);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 500);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
paint.setPathEffect(new CornerPathEffect(100));
canvas.drawPath(path, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

主要的在于

paint.setPathEffect(new CornerPathEffect(100));
  • 1
  • 2

看看构造函数

public CornerPathEffect(float radius)
  • 1
  • 2

参数radius代表了半径,这里的半径就是塞进拐角处圆形的半径,即是用多大半径的圆弧来替换这个拐角。

(2)DashPathEffect

dash line就是虚线的意思,所以这里可以看出,这个类主要是产生虚线效果。 
效果图如下:

图中第一个线段是默认线段,没有使用效果,第二个和第三个使用了,可以看到,他们是虚线。那么二三主要的不同在于他们的相位差,可以看到二三线段的起始位置上,有所不同。先看看该类的构造函数:

public DashPathEffect(float intervals[], float phase)
  • 1
  • 2

其中intervals是间隔,他是一个数组,其中数值必须为偶数,2个为一对,必须成对出现,一对中的第一个代表了线段长度(为0则绘制),第二个代表了空白长度(为0则不留空白)这里可以看出来其实线段2中是由两对数值组成的值如下:

float[] intervals = {100,20,200,50};
  • 1
  • 2

参数中phase代表了相位,线段2为0,代表不移动,线段3为300,移动了300像素。

代码如下:

float[] intervals = {100,20,200,50};

path.moveTo(100, 100);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 500);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
paint.setPathEffect(new DashPathEffect(intervals, 0));
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 900);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
paint.setPathEffect(new DashPathEffect(intervals, 300));
canvas.drawPath(path, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
(3)DiscretePathEffect

discrete意思为离散,这里可能不太好理解,因此直接上图:

线条看起来很凌乱,其实离散就是干这个。先看看构造函数:

public DiscretePathEffect(float segmentLength, float deviation)
  • 1
  • 2

这里有两个参数,第一个segmentLength字面上看就是段长,deviation代表偏差值。 
参数一:指定了原始线段被切分成多长的线段,比如原始线段长度为100.段长设置为20,那么就被切成了5段。

参数二:指定了切割后的小线段于原始位置的偏离距离。

现在看下代码:

path.moveTo(100, 100);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
paint.setPathEffect(new DiscretePathEffect(5,5));
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 500);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
paint.setPathEffect(new DiscretePathEffect(20,5));
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 900);
path.rLineTo(500, 500);
path.rLineTo(500, -500);
paint.setPathEffect(new DiscretePathEffect(5, 20));
canvas.drawPath(path, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
(4)PathDashPathEffect

印章效果,这里先看下效果图:

第一个线条没有做处理,后面三个使用了这个效果。

看下构造函数:

public PathDashPathEffect(Path shape, float advance, float phase,Style style)
  • 1
  • 2

shape:代表了绘制的形状,这里是一个三角形 
advace:绘制位移,上一次绘制这个三角形,和下一次绘制三角形起点之间的位移 
phase:相位,于之前讲解的相同 
style:风格,这里后面三条线就是因为这个参数引起的不同

Style是一个枚举,值如下

TRANSLATE(0),   //平移
ROTATE(1), //旋转
MORPH(2); //变形
  • 1
  • 2
  • 3

这个参数主要控制了线条在转折时候的风格,这里列举的风格和图上的顺序一直。

代码如下:

pathDash.moveTo(20, 0);
pathDash.rLineTo(20,20);
pathDash.rLineTo(-40,0);
pathDash.close(); path.moveTo(100, 100);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 300);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
paint.setPathEffect(new PathDashPathEffect(pathDash,35,0, PathDashPathEffect.Style.TRANSLATE));
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 500);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
paint.setPathEffect(new PathDashPathEffect(pathDash,35,0, PathDashPathEffect.Style.ROTATE));
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 700);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
paint.setPathEffect(new PathDashPathEffect(pathDash,35,0, PathDashPathEffect.Style.MORPH));
canvas.drawPath(path, paint);
  • 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
(5)ComposePathEffect和SumPathEffect

compose组合,sum总和,在这里有什么区别呢,同样的先来看图:

线段2是compose,线段3是sum,看图就已经非常明显,sum只是简单的叠加效果,而compose是组合效果。

代码如下:

Path path = new Path();
float[] intervals = {100, 20};
DashPathEffect dashPathEffect = new DashPathEffect(intervals, 0);
CornerPathEffect cornerPathEffect = new CornerPathEffect(200); path.moveTo(100, 100);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 300);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
paint.setPathEffect(new ComposePathEffect(dashPathEffect, cornerPathEffect));
canvas.drawPath(path, paint); path.reset();
path.moveTo(100, 500);
path.rLineTo(500, 200);
path.rLineTo(500, -200);
paint.setPathEffect(new SumPathEffect(dashPathEffect, cornerPathEffect));
canvas.drawPath(path, paint);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4. setSubpixelText(boolean subpixelText)

这个方法用来开启次像素,让字体更加平滑。次像素是软件通过计算得出的一种像素,是用来缓冲真实像素的边界的。

下面开启了,上面没开启,看起来差别不大。

paint进阶(转)的更多相关文章

  1. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

      Android 高手进阶(21)  版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明地址:http://blog.csdn.net/xiaanming/article/detail ...

  2. Android学习笔记进阶之在图片上涂鸦(能清屏)

    Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...

  3. Java进阶代码

    本文重在温习……不过初学以及进阶高手不可错过 1.  public static void arraycopy(全小写)(object src,int srcPos,object dest,int d ...

  4. 安卓自定义控件(一)Canvas、Paint、Shader、Xfermode

    关于自定义控件,之前就写过一篇自定义控件,上图下字的Button,图片任意指定大小,但是使用效果还是让人感觉不幸福,这次索性彻彻底底地对自定义控件做一次彻彻底底的总结. 我会花4篇博客来介绍自定义控件 ...

  5. [Swift]LeetCode265.粉刷房子 II $ Paint House II

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

  6. 推荐扔物线的HenCoder Android 开发进阶系列 后期接着更新

    官网地址:http://hencoder.com/ 我来做一次辛勤的搬运工 HenCoder:给高级 Android 工程师的进阶手册 HenCoder Android 开发进阶: 自定义 View ...

  7. 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色

    通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...

  8. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)

    连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...

  9. 我的Android进阶之旅------> Android为TextView组件中显示的文本加入背景色

    通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...

随机推荐

  1. java一个对象使用内存

  2. MinMax 容斥 学习笔记

    基本形式 \[ \max(S) = \sum_{T\subseteq S, T \neq \varnothing} (-1)^{|T|-1}\min(T) \] 证明 不提供数学证明. 简要讲一下抽象 ...

  3. 日常Git使用——2019年12月11日16:19:03

    1.git介绍 1.1 什么是git? 什么是Git? 比如一个项目,两个人同时参与开发,那么就把这个项目放在一个公共的地方,需要的时候都可以去获取,有什么改动,都可以进行提交. 为了做到这一点,就需 ...

  4. netty-Selector

    上图中加入一句: socketChannel.configureBlocking(false);//设置为非阻塞的 keyIterator.clear(); 每连接一个SocketChannel 都会 ...

  5. 在python3.7下怎么安装matplotlib与numpy

    一.安装matplotlib 1.在Matplotlib的官网下载电脑对应的版本,网址为:https://pypi.org/project/matplotlib/#files 2.将在下载的.whl文 ...

  6. BDE(一款数据库引擎,通过它可以连接不同数据库)

    BDE(Borland Database Engine)是Inprise公司的数据库引擎,它结合了SQL Links允许程序员通过它能够连接到各种不同的数据库.BDE是BORLAND 数据库引擎的缩写 ...

  7. 安装和使用Redis【转】

    Redis是一个高性能的内存数据库,它体积轻巧性能又高,在企业中被广泛使用. 安装Redis Windows安装 Redis是为Linux系统设计的,但是也有团队为Windows做了移植.我们可以到这 ...

  8. 前端每日实战:36# 视频演示如何利用 CSS 动画原理,在页面上表现日蚀现象

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教程 此视频 ...

  9. LINK : fatal error LNK1561: 必须定义入口点

    转自VC错误:http://www.vcerror.com/?p=1313 问题描述: 错误:LINK : fatal error LNK1561: 必须定义入口点 解决方法: 详细的解决方法可参考V ...

  10. ReplicatorLayer 复制图层

    使用文档介绍: #import <QuartzCore/CALayer.h> NS_ASSUME_NONNULL_BEGIN CA_CLASS_AVAILABLE (10.6, 3.0, ...