Android自定义view利用PathEffect实现动态效果
作者:计蒙不吃鱼 发布时间:2023-08-17 09:35:00
本文实例为大家分享了Android自定义view利用PathEffect实现动态效果的具体代码,供大家参考,具体内容如下
前言
在上一篇此类型的文章中是改变偏移量实现动态效果,借助的方法是drawArc,这篇文章依然是改变偏移量,而借助的是PathEffect的子类。
效果图:
一、首先介绍下PathEffect的一些子类
CornerPathEffect:将Path的各个连接线段之间的夹角用一种更平滑的方式连接,类似于圆弧与切线的效果。 参数radius则是指定圆弧的半径。
DashPathEffect:将Path的线段虚线化,intervals为虚线的ON和OFF的数组,数组中元素数目需要 >= 2; 而phase则为绘制时的偏移量。
DiscretePathEffect:打散Path的线段,使得在原来路径的基础上发生打散效果。 segmentLength指定最大的段长,deviation则为绘制时的偏离量。
PathDashPathEffect:使用Path图形来填充当前的路径,shape指的填充图形,advance是每个图形间的间隔, phase为绘制时的偏移量。,style则是该类自由的枚举值,有三种情况:ROTATE、MORPH和TRANSLATE。ROTATE情况下:线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行连接。MORPH情况下:图形会以发生拉伸或压缩等变形的情况与下一段相连接。TRANSLATE情况下:图形会以位置平移的方式与下一段相连接。
ComposePathEffect:组合效果
SumPathEffect:叠加效果,和ComposePathEffect不同,在表现时会将两个参数的效果都独立的表现出来, 接着将两个效果简单的重叠在一起显示出来
二、看看子类具体的一些代码
private static void makeEffects(PathEffect[] e, float phase) {
e[0] = null; // 无效果
e[1] = new CornerPathEffect(30);//CornerPathEffect
e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);//DashPathEffect
e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
PathDashPathEffect.Style.ROTATE);//PathDashPathEffect
e[4] = new ComposePathEffect(e[2], e[1]);//ComposePathEffect
e[5] = new ComposePathEffect(e[3], e[1]);//ComposePathEffect
}
三、案例实现(CornerPathEffect,PathDashPathEffect,ComposePathEffect)
实现的效果是上序代码的e[5],使用CornerPathEffect实现圆弧效果,而重点是PathDashPathEffect。
PathDashPathEffect里面有几个参数:
new PathDashPathEffect(makePathDash(), 12, phase,
PathDashPathEffect.Style.ROTATE);
第一个参数为小path图形,案例中博主画的是菱形:
private static Path makePathDash() {
Path p = new Path();
p.moveTo(0, 0);
p.lineTo(4, 4);
p.lineTo(8, 0);
p.lineTo(4, -4);
p.moveTo(0, 0);
return p;
}
第二个参数为每个图形间的间隔。
第三个参数为绘制时的偏离量
第四个参数为样式,博主选择的是ROTATE情:线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行连接。
最后使用ComposePathEffect进行组合。
绘制运动路径
private static Path makeFollowPath() {
Path p = new Path();
p.moveTo(0, 0);
p.lineTo(400,0);
p.lineTo(400,400);
p.lineTo(0,400);
p.lineTo(0,0);
return p;
}
修改偏移量实现动态效果
mPhase += 1;
invalidate();
四、源码
public class SampleView extends View {
private Paint mPaint;
private Path mPath;
private PathEffect[] mEffects;
private int mColors;
private float mPhase;
private static void makeEffects(PathEffect[] e, float phase) {
e[0] = null;
e[1] = new CornerPathEffect(30);
e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
e[3] = new PathDashPathEffect(makePathDash(), 12, phase,
PathDashPathEffect.Style.ROTATE);
e[4] = new SumPathEffect(e[3], e[1]);
e[5] = new ComposePathEffect(e[3], e[1]);
}
public SampleView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(6);
mPath = makeFollowPath();
//初始化PathEffect[]
mEffects = new PathEffect[6];
mColors = Color.BLACK;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
RectF bounds = new RectF();
mPath.computeBounds(bounds, false);
canvas.translate(10 - bounds.left, 10 - bounds.top);
makeEffects(mEffects, mPhase);
mPhase += 1;
invalidate();
//选择样式
mPaint.setPathEffect(mEffects[5]);
mPaint.setColor(mColors);
canvas.drawPath(mPath, mPaint);
canvas.translate(0, 28);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
mPath = makeFollowPath();
return true;
}
return super.onKeyDown(keyCode, event);
}
//绘制跑动路径
private static Path makeFollowPath() {
Path p = new Path();
p.moveTo(0, 0);
p.lineTo(400,0);
p.lineTo(400,400);
p.lineTo(0,400);
p.lineTo(0,0);
return p;
}
//绘制跑动的小图标
private static Path makePathDash() {
Path p = new Path();
p.moveTo(0, 0);
p.lineTo(4, 4);
p.lineTo(8, 0);
p.lineTo(4, -4);
p.moveTo(0, 0);
return p;
}
}
来源:https://blog.csdn.net/qq_42761395/article/details/119876461


猜你喜欢
- 在Android开发中,往往要用到自定义的控件来实现我们的需求或效果。在使用自定义 控件时,难免要用到自定义属性,那怎么使用自定义属性呢?在
- 本文实例讲述了android编程实现sd卡读取数据库的方法。分享给大家供大家参考,具体如下:先在 Manifest 里添加权限:<us
- 本文主要介绍Java中的rmi的基本使用1:项目架构api:主要是接口的定义,url地址,端口号rmiconsumer:rmi服务的调用者r
- 前言哈哈哈哈哈。。。。。。。。问题终于解决了,让我得瑟一会(吗卖批,折腾了两天)~~~如果你的Android Studio出现以下错误,那么
- 如何避开在ListView等AdapterView上动态添加删除项的陷阱,下面就为大家分享,具体内容如下首先,定义如下array资源,作为列
- 本文实例讲述了C#数据结构之堆栈(Stack)。分享给大家供大家参考,具体如下:堆栈(Stack)最明显的特征就是“先进后出”,本质上讲堆栈
- 目录一、需求二、步骤三、结果一、需求把以下txt中含“baidu”字符串的链接输出到一个文件,否则输出到另外一个文件。二、步骤1.LogMa
- SpringBoot Data JPA实现 一对多、多对一关联表查询开发环境IDEA 2017.1Java1.8SpringBoot 2.0
- 前言内存管理的目的就是让我们在开发过程中有效避免我们的应用程序出现内存泄露的问题。内存泄露相信大家都不陌生,我们可以这样理解:「没有用的对象
- 本文实例讲述了C#实现将汉字转化为2位大写的16进制Unicode的方法。分享给大家供大家参考。具体实现方法如下:说明:str.ToStri
- 最近一直都在学习Java,发现目前Java招聘中,mybatis出现的频率挺高的,可能是目前Java开发中使用比较多的数据库ORM框架。于是
- 线程池execute与submit区别在使用线程池的时候,看到execute()与submit()方法。都可以使用线程池执行一个任务,但是两
- 将Fragment与Layout结合使用,一般都是主Activity以frame填充Activity的方式交互管理Fragment :1.由
- 一、Stream流引入Lambda表达式,基于Lambda所带来的函数式编程,又引入了一个全新的Stream概念,用于解决集合类库既有的鼻端
- 1、仿照微信空间上传图片,显示图片数量以及超过最大,上传按钮隐藏功能2、上效果图3、上代码,主要是Adapter类/** * Created
- 本文实例为大家分享了Java实现聊天室界面的具体代码,供大家参考,具体内容如下服务器端:package Server; impor
- 这几天面试中有遇到关于main数组中的args数组传值的问题,一般是从命令提示符中传值,也可以直接在java代码中赋值。而且这个数组的长度是
- 本文实例讲述了winform用datagridview制作课程表的方法。分享给大家供大家参考。具体分析如下:课程表的最终效果如下图所示:具体
- 场景:简单工厂时候,我设计了一个场景,有三种剑去打怪,这时候,需求变化了,我三种剑变成了,匕首、剑以及木棒,想要用工厂方法来实现,怎么弄?1
- 随着微信的到来,二维码越来越火爆,随处能看到二维码,比如商城里面,肯德基,餐厅等等,对于二维码扫描我们使用的是google的开源框架Zxin