Android实现漂亮的波纹动画
Android实现漂亮的波纹动画
本文章讲述如何使用二维画布canvas和camera、矩阵实现二、三维波纹动画效果(波纹大小变化、画笔透明度变化、画笔粗细变化)
一、UI界面
界面主要分为三部分
第一部分:输入框,根据输入x轴、Y轴、Z轴倾斜角度绘制波纹动画立体效果
第二部分:点击按钮PLAY:开始绘制动画;点击按钮STOP:停止绘制动画
第三部分:绘制波纹动画的自定义view

activity_main.xml实现如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="16dp"android:gravity="center"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_marginBottom="8dp"><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"android:gravity="center_horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="X轴倾斜" /><EditTextandroid:id="@+id/editText_X"android:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="number"android:text="0"/></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"android:gravity="center_horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Y轴倾斜" /><EditTextandroid:id="@+id/editText_Y"android:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="number"android:text="0"/></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"android:gravity="center_horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Z轴倾斜" /><EditTextandroid:id="@+id/editText_Z"android:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="number"android:text="0"/></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"android:paddingTop="16dp"><Buttonandroid:id="@+id/playButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Play"android:layout_marginEnd="8dp"/><Buttonandroid:id="@+id/stopButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Stop"android:layout_marginEnd="8dp"/></LinearLayout><FrameLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:layout_gravity="center"><!-- WaveView --><com.example.waveanimationbysingleview.animation.WaveViewandroid:id="@+id/wave_view"android:layout_width="match_parent"android:layout_height="606dp"android:layout_gravity="center" /></FrameLayout></LinearLayout>
二、自定义view实现
新建一个WaveView类继承自View,声明类成员变量和实现构造函数初始化
public class WaveView extends View{private RippleAnimationInfo mRippleInfo;//动画属性类,包括最大、最小半径,光圈等private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);private float centerX, centerY; //绘制画布中心点private float[] mRadiusArray; // 存储当前绘制每圈光波的半径private float[] mAlphaArray; //存储当前绘制每圈光波的透明度private float[] mStrokenArray; //存储当前绘制每圈光波的画笔宽度private final Camera mCamera = new Camera();//相机private final Matrix mMatrix = new Matrix();//矩阵private final RectF mRectF = new RectF();private Boolean mIsDrawing = false;//是否绘制标志位private Bitmap mLogoBitmap;//中心点表情😝logoprivate AnimatorSet mAnimatorSet = new AnimatorSet();//多动画组合类private List<Animator> mAnimatorList = new ArrayList<>();//存储动画列表public WaveView(Context context) {super(context);init();}public WaveView(Context context, AttributeSet attrs) {super(context, attrs);init();}public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}
构造函数初始化
添加动画
- 圆圈等比变大动画
- 透明度渐变动画
- 画笔由细变粗动画
private void initAnimation() {int rippleDelay = mRippleInfo.durationTime/mRippleInfo.rippleCount;for (int i = 0; i < mRippleInfo.rippleCount; i++) {//动画1-半径变大final int index = i;ValueAnimator radiusAnimator = ValueAnimator.ofFloat(mRippleInfo.minRadius, mRippleInfo.maxRadius);radiusAnimator.setDuration(mRippleInfo.durationTime); // 动画持续时间radiusAnimator.setStartDelay(i * rippleDelay); // 延迟启动radiusAnimator.setRepeatCount(ValueAnimator.INFINITE);radiusAnimator.setRepeatMode(ValueAnimator.RESTART);radiusAnimator.addUpdateListener(animation -> {mRadiusArray[index] = (float) animation.getAnimatedValue();invalidate(); // 重绘视图});//动画2-画笔变粗ValueAnimator strokeAnimator = ObjectAnimator.ofFloat(mRippleInfo.minStrokenWidth, mRippleInfo.maxStrokenWidth);strokeAnimator.setDuration(mRippleInfo.durationTime); // 动画持续时间strokeAnimator.setStartDelay(i * rippleDelay); // 延迟启动strokeAnimator.setRepeatCount(ValueAnimator.INFINITE);strokeAnimator.setRepeatMode(ValueAnimator.RESTART);strokeAnimator.addUpdateListener(animation -> {mStrokenArray[index] = (float) animation.getAnimatedValue();invalidate(); // 重绘视图});//动画3-颜色淡出ValueAnimator alphaAnimator = ObjectAnimator.ofFloat( 0.1f, 0.8f, 0.8f,0.4f, 0);alphaAnimator.setDuration(mRippleInfo.durationTime); // 动画持续时间alphaAnimator.setStartDelay(i * rippleDelay); // 延迟启动alphaAnimator.setRepeatCount(ValueAnimator.INFINITE);alphaAnimator.setRepeatMode(ValueAnimator.RESTART);alphaAnimator.addUpdateListener(animation -> {mAlphaArray[index] = (float) animation.getAnimatedValue();invalidate(); // 重绘视图});mAnimatorList.add(radiusAnimator);mAnimatorList.add(strokeAnimator);mAnimatorList.add(alphaAnimator);}mAnimatorSet.playTogether(mAnimatorList);}
应用矩阵变换
重写ondraw
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (!mIsDrawing){return;}canvas.save();// 计算中心点centerX = getWidth() / 2.0f;centerY = getHeight() / 2.0f;canvas.concat(mMatrix);// 将矩阵应用到画布上//绘制多圈波纹for (int i = 0; i < mRippleInfo.rippleCount; i++) {if (mRadiusArray[i] > 0) {paint.setStrokeWidth(mStrokenArray[i]);paint.setAlpha((int)(255 * mAlphaArray[i]));canvas.drawCircle(centerX, centerY,mRadiusArray[i],paint);}}// 中心点绘制 logocanvas.drawBitmap(mLogoBitmap, (getWidth()- mRippleInfo.minRadius)/2, (getHeight()- mRippleInfo.minRadius)/2, null);canvas.restore();}
二、二维波纹动画
waveAnimation_2D
三、三维波纹动画
waveAnimation_3D
相关文章:
Android实现漂亮的波纹动画
Android实现漂亮的波纹动画 本文章讲述如何使用二维画布canvas和camera、矩阵实现二、三维波纹动画效果(波纹大小变化、画笔透明度变化、画笔粗细变化) 一、UI界面 界面主要分为三部分 第一部分:输入框,根据输入x轴、Y轴、Z轴倾…...
JAVA学习笔记038——bean的概念和常见注解标注
什么是bean? Bean 就是 被 Spring 管理的对象,就像工厂流水线上生产的“标准产品”。这些对象不是你自己 new 出来的,而是由 Spring 容器(一个超级工厂)帮你创建、组装、管理。 由 Component、Service、Controller 等注解标记的…...
自然语言处理NLP入门 -- 第十节NLP 实战项目 2: 简单的聊天机器人
一、为什么要做聊天机器人? 在互联网时代,我们日常接触到的“在线客服”“自动问答”等,大多是以聊天机器人的形式出现。它能帮我们快速回复常见问题,让用户获得及时的帮助,并在一定程度上减少人工客服的压力。 同时&…...
【网络安全 | 渗透工具】小程序反编译分析源码 | 图文教程
未经许可,禁止转载。 本文仅供学习使用,严禁用于非法渗透测试,笔者不承担任何责任。 文章目录 1、下载Proxifier2、下载反编译工具unveilr3、寻找小程序文件包4、对文件包进行反编译5、对源码进行分析6、渗透思路6.1、查找敏感信息泄露6.2、解析加解密逻辑6.3、枚举 API 接口…...
uniapp 系统学习,从入门到实战(六)—— 样式与布局
全篇大概 4700 字(含代码),建议阅读时间 30min 📚 目录 Flex 布局在 UniApp 中的应用响应式设计与适配多端使用 SCSS 提升样式开发效率实战案例演示总结 1. Flex 布局在 UniApp 中的应用 1.1 基础布局实现 通过 display: flex 快速构建弹性容器&#…...
‘ts-node‘ 不是内部或外部命令,也不是可运行的程序
新建一个test.ts文件 let message: string = Hello World; console.log(message);如果没有任何配置的前提下,会报错’ts-node’ 不是内部或外部命令,也不是可运行的程序。 此时需要安装一下ts-node。 npm install...
mysql 全方位安装教程
下载 MySQL 【官网下载地址】 注意要选择较大的哪个安装包,小的安装包是一个安装器。 我们不用登录,直接下载 直接运行下载好的安装包 MySQL如果是 安装包安装, 可以图形化界面自主配置 如果是压缩包解压, 可以配置 配置文件, 可以解压安装到指定的…...
22-接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 方法一:双指针法 思路 使用两个指针 left 和 right 分别指向数组的两端,同时记录左边的最大高度 leftMax 和右边的最大高度 rig…...
使用Spring Boot与达梦数据库(DM)进行多数据源配置及MyBatis Plus集成
使用Spring Boot与达梦数据库(DM)进行多数据源配置及MyBatis Plus集成 在现代企业级应用开发中,处理多个数据源是一个常见的需求。本文将详细介绍如何使用Spring Boot结合达梦数据库(DM),并通过MyBatis Plus来简化数据库操作&…...
leetcode28 找出字符串第一个匹配值的下标 KMP算法
KMP 算法——快速的从主串中找到模式串 当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。 KMP 算法 比较指针不回溯,仅仅是后移模式串。 每次不匹配的时候,找之前已匹配部分…...
【Bug】natten:安装报错(临近注意力机制的高效cuda内核实现)
正常安装natten报错 pip install natten 报错 可以尝试使用以下网站进行安装 https://shi-labs.com/natten/ 可以根据自己的cuda与pytorch版本进行安装 之间复制命令即可,不需要进行任何修改...
AI 实战2 - face -detect
人脸检测 环境安装源设置conda 环境安装依赖库 概述数据集wider_face转yolo环境依赖标注信息格式转换图片处理生成 train.txt 文件 数据集展示数据集加载和处理 参考文章 环境 安装源设置 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/f…...
Spring Boot 项目开发流程全解析
目录 引言 一、开发环境准备 二、创建项目 三、项目结构 四、开发业务逻辑 1.创建实体类: 2.创建数据访问层(DAO): 3.创建服务层(Service): 4.创建控制器层(Controller&…...
从Java到MySQL8源码:深入解析PreparedStatement参数绑定与执行机制
引言 在数据库开发中,PreparedStatement(预处理语句)是防止SQL注入、提升性能的重要工具。它通过分离SQL结构与参数值,不仅增强了安全性,还能利用预编译优化执行效率。本文将从Java JDBC驱动和MySQL 8源码的双重视角&…...
mysql的主从同步
1、异步复制:这是MySQL默认的复制模式。在这种模式下,主库在执行完客户端提交的事务后会立即将结果返回给客户端,并不关心从库是否已经接收并处理。这种模式的优点是实现简单,但缺点是如果主库崩溃,已经提交的事务可能…...
工程化与框架系列(10)--微前端架构
微前端架构 🏗️ 微前端是一种将前端应用分解成更小、更易管理的独立部分的架构模式。本文将详细介绍微前端的核心概念、实现方案和最佳实践。 微前端概述 🌟 💡 小知识:微前端的核心理念是将前端应用分解成一系列独立部署、松耦…...
【3天快速入门WPF】11-附加属性
目录 1. 步骤1:定义附加属性2. 示例代码3. 步骤2:在XAML中使用附加属性3.1. 示例代码4. 步骤3:扩展使用场景4.1. 示例代码5. 总结上一篇讲到了依赖属性,本篇主要想说一下附加属性。 在WPF中,附加属性(Attached Property)是一种特殊的依赖属性,允许你在不属于某个类的控…...
MySQL并发知识(面试高频)
mysql并发事务解决 不同隔离级别下,mysql解决并发事务的方式不同。主要由锁机制和MVCC(多版本并发控制)机制来解决并发事务问题。 1. mysql中的锁有哪些? 表级锁: 场景:表级锁适用于需要对整个表进行操作的情况,例如…...
现存脑容知识库
Redis import queue import threading import asyncio 异步:在一个线程内,等待的时候可以切换到其他任务。 多线程:每个线程独立运行,同时处理多个任务。 回调函数 网络请求(JavaScript)在浏览器中&a…...
Mysql-如何理解事务?
一、事务是什么东西 有些场景中,某个操作需要多个sql配合完成: 例如: 李四这个月剩下的前不够交房租了,找张三借1000元急用: (1)给张三的账户余额 减去1000元 updata 账户表 set money money -…...
Pytest参数化测试中文乱码?这2个隐藏技巧让你的测试报告清晰可读
Pytest参数化测试中文乱码?这2个隐藏技巧让你的测试报告清晰可读 在Python自动化测试领域,Pytest凭借其简洁的语法和强大的功能已成为开发者的首选工具。特别是它的参数化测试功能,能够高效验证多组输入数据下的代码行为。但当我们尝试用中文…...
AdminBSB表格组件完全指南:jQuery DataTable高级用法
AdminBSB表格组件完全指南:jQuery DataTable高级用法 【免费下载链接】AdminBSBMaterialDesign AdminBSB - Free admin panel that is based on Bootstrap 3.x with Material Design 项目地址: https://gitcode.com/gh_mirrors/ad/AdminBSBMaterialDesign Ad…...
从特征多项式到行列式:揭秘矩阵特征值之积的几何意义
1. 特征多项式:打开矩阵奥秘的钥匙 我第一次接触特征多项式时,完全被这个抽象的概念搞晕了。直到有一天,我的导师用了一个简单的比喻:"特征多项式就像是矩阵的DNA检测报告,它能告诉我们这个矩阵最本质的特性。&qu…...
达摩院CAM++说话人识别模型实战:5分钟搞定Modelscope部署与中文测试
达摩院CAM说话人识别模型实战:5分钟搞定Modelscope部署与中文测试 语音技术正在重塑人机交互的边界,而说话人识别作为其中的核心能力之一,已经从实验室走向工业级应用。达摩院开源的CAM模型以其卓越的准确率和计算效率,正在成为开…...
Docker核心技能全解析,容器化部署不再难
一、Docker核心概念:搞懂这3个词,入门就成功了一半 在动手操作前,先理清Docker的核心组件,避免陷入"会操作不会原理"的困境: 容器(Container):Docker的核心运行单元&…...
UNTRUNC:视频修复破局者——从文件截断到数据重生的技术解密
UNTRUNC:视频修复破局者——从文件截断到数据重生的技术解密 【免费下载链接】untrunc Restore a damaged (truncated) mp4, m4v, mov, 3gp video. Provided you have a similar not broken video. 项目地址: https://gitcode.com/gh_mirrors/unt/untrunc 诊…...
LangChain提示词模板避坑指南:从PromptTemplate到ChatPromptTemplate,我踩过的那些坑
LangChain提示词模板实战避坑手册:从语法陷阱到消息类型混用的深度解析 第一次接触LangChain的提示词模板时,我以为这不过是个简单的字符串格式化工具——直到凌晨三点还在调试那个诡异的TypeError。如果你也曾在PromptTemplate和ChatPromptTemplate之间…...
YimMenu全面指南:GTA V游戏体验的终极优化方案
YimMenu全面指南:GTA V游戏体验的终极优化方案 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu …...
XP.css终极指南:如何用CSS完美复刻Windows经典界面
XP.css终极指南:如何用CSS完美复刻Windows经典界面 【免费下载链接】XP.css A CSS framework for building faithful recreations of operating system GUIs. 项目地址: https://gitcode.com/gh_mirrors/xp/XP.css 你是否怀念Windows XP和Windows 98那经典的…...
告别学术阅读障碍:重新定义PDF翻译体验
告别学术阅读障碍:重新定义PDF翻译体验 【免费下载链接】PDFMathTranslate PDF scientific paper translation with preserved formats - 基于 AI 完整保留排版的 PDF 文档全文双语翻译,支持 Google/DeepL/Ollama/OpenAI 等服务,提供 CLI/GUI…...
