自定义View之会动的闪电

2024-06-13 13:58

本文主要是介绍自定义View之会动的闪电,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前两天在csdn手机端上看到貌似是有个app具有这个闪电的loading标志,非常感兴趣,正好目前正在学习自定义view,所以就想自己来实现一下,还好自己完成了,不是很难~
效果图:
闪电效果图
由于是手机上截的图,所以没有弄成动态的,大家体谅一下哈。
下面是代码:
首先自定义view的属性,我先以属性的形式实现了,大家如果想做成loading的效果的话,可以自己去实现。。

```
<resources><declare-styleable name="LightView"><attr name="light_color" format="color"></attr><attr name="bg_color" format="color"></attr><attr name="speed" format="integer"></attr><attr name="lightSize" format="dimension"></attr></declare-styleable></resources>

这里面我定义了light_color 首次闪电的绘制颜色,bg_color 第二次绘制闪电的颜色,后面如果绘制的话,其实就不分首次和下一次了,因为需要来回的转换,speed 绘制的速度,lightSize 闪电的高度
下面看具体实现代码:

public class LightView extends View {private int mLightColor, mBgColor, mspeed, addSpeed = 1, mLightSize;private Paint paint;private int mWidth, mHeight, measureHeight;private Path path;private boolean flag = false;private RectF rect;public LightView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public LightView(Context context) {this(context, null);}public LightView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightView, defStyleAttr, 0);mLightColor = a.getColor(R.styleable.LightView_light_color, Color.YELLOW);mBgColor = a.getColor(R.styleable.LightView_bg_color, Color.RED);mspeed = a.getInt(R.styleable.LightView_speed, 1);mLightSize = a.getDimensionPixelSize(R.styleable.LightView_lightSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 17,getResources().getDisplayMetrics()));a.recycle();paint = new Paint();paint.setStyle(Paint.Style.FILL);paint.setAntiAlias(true);paint.setStrokeWidth(1);paint.setColor(mLightColor);rect = new RectF();new Thread(new Runnable() {@Overridepublic void run() {while (true) {//高度的增量addSpeed += 10;postInvalidate();try {Thread.sleep(mspeed);//绘制的速度} catch (Exception e) {e.printStackTrace();}}}}).start();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int heightMode = MeasureSpec.getMode(heightMeasureSpec);measureHeight = MeasureSpec.getSize(heightMeasureSpec);if (heightMode == MeasureSpec.EXACTLY) {mHeight = Math.min(measureHeight, mLightSize);} else {mHeight = mLightSize;}mWidth = 2 * mHeight / 3;//以高度来决定view的宽度,设置宽度永远为高度的三分之二。。我是觉得这样好看。。=。=//使用path绘制闪电形状path = new Path();path.moveTo(mWidth * 2 / 3, 0);path.lineTo(mWidth / 2, 4 * mHeight / 9);path.lineTo(mWidth * 2 / 3, 4 * mHeight / 9);path.lineTo(mWidth / 3, mHeight);path.lineTo(mWidth / 2, 5 * mHeight / 9);path.lineTo(mWidth / 3, 5 * mHeight / 9);path.close();setMeasuredDimension(mWidth, mHeight);}@Overrideprotected void onDraw(Canvas canvas) {rect.top = 0;rect.left = 0;rect.right = mWidth;rect.bottom = mHeight;paint.setColor(Color.GREEN);canvas.drawRoundRect(rect, mWidth / 2, mHeight / 2, paint);//通过对切割画布的高度的判断,判断是否第二次的绘制已经完成,然后改变初次绘制的闪电的颜色if (addSpeed >= mHeight) {addSpeed = 0;if (!flag) {flag = true;} else {flag = false;}}if (!flag) {paint.setColor(mLightColor);canvas.drawPath(path, paint);//绘制完全的闪电paint.setColor(mBgColor);canvas.clipRect(0, 0, mWidth, addSpeed);//通过切割画布,在重新绘制闪电,并不会对已经绘制过的图形产生影响canvas.drawPath(path, paint);} else {paint.setColor(mBgColor);canvas.drawPath(path, paint);paint.setColor(mLightColor);canvas.clipRect(0, 0, mWidth, addSpeed);canvas.drawPath(path, paint);}}}

其实这里面主要是对基础的path和clipRect的理解
找到一个介绍clipRect的不错的文章,摘过来
android的clip有以下两点疑问:
Clip(剪切)的时机
Clip中的Op的参数的意思。

通常咱们理解的clip(剪切),是对已经存在的图形进行clip的。但是,在android上是对canvas(画布)上进行clip的,要在画图之前对canvas进行clip,如果画图之后再对canvas进行clip不会影响到已经画好的图形。一定要记住clip是针对canvas而非图形。

接下来通过android自带的APIdemo Clipping例子详细讲述Clip中的Op的参数的意思。Android提供clipRect、clipPath和clipRegion剪切区域的API。
Op一共有 DIFFERENCE,INTERSECT,UNION,XOR, REVERSE_DIFFERENCE, REPLACE六种选择。

例子:
在canvas上剪切从(0,0)到(60,60)的方块。下图蓝色区域加紫色区域。
在canvas上剪切从(40,40)到(100,100)的方块。下图橄榄色区域加紫色区域。
在canvas上剪切从(0,0)到(100,100)的方块。
这里写图片描述

先在第二方块上加上Op参数例如:canvas.clipRect(40, 40, 100, 100, Region.Op. DIFFERENCE);
首先,需要搞清楚Op参数针对的对象。接着了解其含义。
Op参数针对的对象是之前剪切的区域以及当前要剪切的区域。
在本例中涉及到区域是从(0,0)到(60,60)的方块和从(40,40)到(100,100)的方块。
那有哪些含义呢?就是表示当前要剪切的区域与之前剪切过的之间的关系。

DIFFERENCE:之前剪切过除去当前要剪切的区域(蓝色区域)。
INTERSECT:当前要剪切的区域在之前剪切过内部的部分(紫色区域)。
UNION:当前要剪切的区域加上之前剪切过内部的部分(蓝色区域+紫色区域+橄榄色区域)。
XOR:异或,当前要剪切的区域与之前剪切过的进行异或。(蓝色区域+橄榄色区域)。
REVERSE_DIFFERENCE:与DIFFERENCE相反,以当前要剪切的区域为参照物,当前要剪切的区域除去之前剪切过的区域(橄榄色区域);
REPLACE:用当前要剪切的区域代替之前剪切过的区域。(橄榄色区域+紫色区域);
没带Op参数效果与INTERSECT的效果一样,两个区域的交集。

这篇关于自定义View之会动的闪电的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1057500

相关文章

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

Oracle type (自定义类型的使用)

oracle - type   type定义: oracle中自定义数据类型 oracle中有基本的数据类型,如number,varchar2,date,numeric,float....但有时候我们需要特殊的格式, 如将name定义为(firstname,lastname)的形式,我们想把这个作为一个表的一列看待,这时候就要我们自己定义一个数据类型 格式 :create or repla

MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)

1、MVC MVC(Model-View-Controller) 是一种常用的架构模式,用于分离应用程序的逻辑、数据和展示。它通过三个核心组件(模型、视图和控制器)将应用程序的业务逻辑与用户界面隔离,促进代码的可维护性、可扩展性和模块化。在 MVC 模式中,各组件可以与多种设计模式结合使用,以增强灵活性和可维护性。以下是 MVC 各组件与常见设计模式的关系和作用: 1. Model(模型)

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d

一步一步将PlantUML类图导出为自定义格式的XMI文件

一步一步将PlantUML类图导出为自定义格式的XMI文件 说明: 首次发表日期:2024-09-08PlantUML官网: https://plantuml.com/zh/PlantUML命令行文档: https://plantuml.com/zh/command-line#6a26f548831e6a8cPlantUML XMI文档: https://plantuml.com/zh/xmi

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

鸿蒙开发中实现自定义弹窗 (CustomDialog)

效果图 #思路 创建带有 @CustomDialog 修饰的组件 ,并且在组件内部定义controller: CustomDialogController 实例化CustomDialogController,加载组件,open()-> 打开对话框 , close() -> 关闭对话框 #定义弹窗 (CustomDialog)是什么? CustomDialog是自定义弹窗,可用于广告、中