WaterView 自定义圆形水波进度

2023-10-30

这几天不是很忙,完成了工作,利用闲暇的时间来完成一下以前不会玩的自定义动画,自定义圆形水波进度,这个以前把我难死了,死活不会。都怪自己太菜了。那么现在来看看到底难不难,真正最简单的实现方法。

先来了解下path类的基本方法。

移动起点    moveTo  移动下一次操作的起点位置
设置终点    setLastPoint    重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同
连接直线    lineTo  添加上一个点到当前点之间的直线到Path
闭合路径    close   连接第一个点连接到最后一个点,形成一个闭合区域
添加内容    addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo   添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别)
是否为空    isEmpty 判断Path是否为空
是否为矩形   isRect  判断path是否是一个矩形
替换路径    set 用新的路径替换到当前路径所有内容
偏移路径    offset  对当前路径之前的操作进行偏移(不会影响之后的操作)
贝塞尔曲线   quadTo, cubicTo 分别为二次和三次贝塞尔曲线的方法
rXxx方法  rMoveTo, rLineTo, rQuadTo, rCubicTo 不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
填充模式    setFillType, getFillType, isInverseFillType, toggleInverseFillType  设置,获取,判断和切换填充模式
提示方法    incReserve  提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)
布尔操作(API19) op  对两个Path进行布尔运算(即取交集、并集等操作)
计算边界    computeBounds   计算Path的边界
重置路径    reset, rewind   清除Path中的内容
reset不保留内部数据结构,但会保留FillType.
rewind会保留内部的数据结构,但不保留FillType
矩阵操作    transform   矩阵变换

这里我们要用的就是path里面的quadTo,二次贝塞尔曲线,二次贝塞尔曲线这个可以资料,这里重点不再这里。
http://blog.csdn.net/z82367825/article/details/51599245
canvas.clipPath();这个方法也很重要,剪切,Clip(剪切)的时机:通常理解的clip(剪切),是对已经存在的图形进行clip的。但是,在android上是对canvas(画布)上进行clip的,要在画图之前对canvas进行clip,如果画图之后再对canvas进行clip不会影响到已经画好的图形。一定要记住clip是针对canvas而非图形。
以前做圆角图片的时候用这个
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));这俩作用不一样,setXfermode这个主要是针对图片的处理。

看看这波涛汹涌的效果

水波加载动画

全部代码在下面


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Region;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by 
 */

public class WaterView extends View {

    final String TAG = this.getClass().getSimpleName();


    int h, w;//控件的宽高
    int waveHight = 50;//波浪的高度,也可以说是控制点的高度
    int waveW = 800;//波长
    int baseLine;// 基准线,可以控制水波上涨
    int halfwave;//半个波长
    int offset = 5;//偏移量,控制波浪的滚动
    int waveCount;//控件可以放多少个波长

    static boolean isStart = false;

    private Paint framePaint = new Paint();
    private Paint circlePaint = new Paint();
    int frameColor = Color.RED;
    private Path framePath = new Path();
    WaveThread mWaveThread;

    public WaterView(Context context) {
        this(context, null);
    }

    public WaterView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WaterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isStart = false;
        mWaveThread = null;
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.h = h;
        this.w = w;
        baseLine = h;
        waveCount = w / waveW + 1;//这里必须加上1,int  3/2=1,这里就只显示一个波长,还有半个波长不显示。
        framePath.reset();

    }

    private void init() {
        framePaint.setColor(frameColor);
        framePaint.setAntiAlias(true);
        halfwave = waveW / 2;
        circlePaint.setColor(Color.BLUE);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(3);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        framePath.reset();
        framePath.addCircle(w / 2, h / 2, w / 2, Path.Direction.CW);
        canvas.clipPath(framePath, Region.Op.INTERSECT);
        canvas.drawCircle(w * 1.0f / 2, h * 1.0f / 2, h * 1.0f / 2, circlePaint);

        framePath.reset();
        framePath.moveTo(-2 * halfwave + offset, baseLine);
        for (int i = -2; i < waveCount * 2; i++) {
            if (i % 2 == 0) {
                framePath.quadTo(i * halfwave + halfwave / 2 + offset, baseLine + waveHight, i * halfwave + halfwave + offset, baseLine);
            } else {
                framePath.quadTo(i * halfwave + halfwave / 2 + offset, baseLine - waveHight, i * halfwave + halfwave + offset, baseLine);
            }
        }
        framePath.lineTo(w, h);
        framePath.lineTo(0, h);
        framePath.close();
        canvas.drawPath(framePath, framePaint);
    }

    public void start() {
        if (!isStart) {
            isStart = true;
            mWaveThread = new WaveThread();
            mWaveThread.start();
        }
    }

    public void stop() {
        isStart = false;
    }

    class WaveThread extends Thread {


        @Override
        public void run() {
            super.run();
            while (isStart) {
                offset += 15;
                if (offset >= waveW)
                    offset = offset - waveW;
                if (baseLine < 0) {
                    isStart = false;
                    Log.e(TAG, "run: ");


                }
                baseLine -= 2;
                try {
                    postInvalidate();
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

这种效果还有一种实现方式,相对麻烦点
主要就是sin函数,y = Asin(wx+b)+h ,这个公式里:w影响周期,A影响振幅,h影响y位置,b为初相。根据函数计算出两个波浪的path ,最后进行绘制,有兴趣的盆友可以研究下这个。

想了解更多,可以添加公众号

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WaterView 自定义圆形水波进度 的相关文章

  • MMDrawerController(0.6.0) 文档翻译(简介,非API文档)

    Mutual Mobile Drawer Controller 随着使用抽屉效果的应用越来越多 MMDrawerController应运而生 MMDrawerController是一个仅支持侧边抽屉导航的轻量级库 同时库中还提供了定制展现
  • 在运行中修改unity的animator中某个状态的速度

    要在运行中修改动画播放速度的话不能用UnityEditor 只能修改animator的速度 不能修改animator里某个状态的速度 运行中修改animator的速度不会保存 但是运行中修改animator里某个状态的速度则会保存下来 这大
  • BottomNavigationView取消水波纹动画

    BottomNavigationView取消水波纹动画 不得不说 BottomNavigationView 以下简称BNV fragment ViewPager用来实现一些基础的项目效果实在是不错 但BNV自带的缩放动画 水波纹动画使得用户
  • 烟雾调节器

    先看效果 烟雾调节展示 再看代码
  • 【Unity3D】Unity5.6的Mecanim Animator动画系统结合MMD4Mecanim插件舞蹈动画

    1 下载MMD4Mecanim 官网 http stereoarts jp 我用的是最新版的MMD4Mecanim Beta 20170423 zip Unity是5 6 0版本的 2 解压后导入MMD4Mecanim unitypacka
  • vue 路由切换动画(滑入,滑出效果)

    最近做的一个小项目 需要做路由切换 页面滑入滑出的效果 总结下实现的思路和方法 router view 用 transition 标签包裹 router view 组件 动态添加动画名 data 里定义transitionName变量
  • 1896-2021历届奥运会奖牌榜动态排序(Matplotlib图表动画)

    摘 要 在制作动态排序动画之前 我们看一下数据的整理情况 a 对第1 种大部分数据的情况 先爬取下来 输出到excel 1 b 对第2 种小部分数据的情况 也先爬取下来 输出到另一个excel 2 c 对第3 种个别的 还有第31 32届的
  • 算法——排序——归并排序图解动画

    归并排序 简介 代码示例 排序过程 分解 合并 时间复杂度 空间复杂度 稳定性 简介 归并排序分为两部分 分解 合并 分解 归并算法会把数组分成两个长度相同的子数组 直到无法再分割 每个数组只有一个元素 此过程不消耗时间资源 对应的时间复杂
  • 第36.1节 动画-刚体动画控制

    目录 本节功能 具体实现 存放动画 寻找动画 播放 暂停 复位 加速 减速 最后用一个事件响应来联接这一切 所有代码 本节功能 本节后几个章节会介绍和动画有关的课程 本节实现一个从3DMAX导出的地板破碎的动画的控制 这类动画叫做刚体动画
  • unity制作和输出摄像机环绕动画

    1 需要用到两个官方插件Cinemachine以及Recorder 2 第一步设置摄像机 创建一个虚拟相机CM vcam1 这时主摄像机会自动加载Cinemachinebrain组件 并指定CM1 3 设置CM1的参数 创建空物体命名为ta
  • Unity中的动画系统

    学习动画系统过程中的一些笔记 概述 Unity 的动画系统基于动画剪辑 Animation Clips 的概念 每个动画剪辑可以被认为是一个单一的线性记录 由动画状态机 Animator Controller 将一个个线性记录组成类似结构化
  • Flutter仿抖音点击进入直播间按钮动画实现

    利用flutter仿抖音点击进入直播间动画效果 效果图 对于这个widget 已经封装成插件 供大家依赖使用 askai animation button last version 组件的一些必选属性 const KaiAnimationB
  • 微信小程序实现一些炫酷的loading动画

    1 实现效果 2 实现原理 伪元素 css3动画 transform 3 实现代码 从上到下 从左到右依次的代码如下
  • 动画状态机Animator-Unity3d

    该模型一直处于奔跑状态 点击跳跃则跳跃一次后回到奔跑状态 点击攻击后则攻击一次回到奔跑状态 控制代码如下 using UnityEngine using System Collections 该人物一直处于奔跑状态 点击跳跃则跳跃一次后回到
  • CSS鼠标滑过翻转动画图标

    html css鼠标放上去变大效果 效果如下动态图 目录层级 代码如下 html文件 index html li li
  • Android 4.4.2引入的超炫动画库

    酷炫 作者博客 http rkhcy github io 源码地址 https github com Rkhcy TransitionNote Google Demo https github com android platform fr
  • Qt 自定义提示框 类似QMessageBox

    前言 为什么需要设计自定义提示框呢 1 Qt自带的提示框样式单一 2 提示框的太小 3 界面风格跟项目的不搭配 程序执行效果 源码下载地址 https gitee com jiang bin yu qt custom prompt box
  • Unity处决动画实现思路

    前言 不只是处决动画 只要是需要多个动画目标配合的都可以参考下面的思路 方案一 去除掉动画的位移部分 xz 在合适的时机移动到固定的位置双方同时播放动画 比如实现下图中狼和鹿的捕猎动画 我的做法是在要开始播放处决动画之前先让狼位移到固定位置
  • Vue实现动画的几种方式

    vue内置组件transition 元素出现和消失都呈现动画
  • libgdx导入blender模型

    具体就是参考 官网 https libgdx com wiki graphics 3d importing blender models in libgdx blender 教程可以看八个案例教程带你从0到1入门blender 已完结 这里

随机推荐

  • hashMap和hashTable的区别以及HashMap的底层原理?

    hashMap和hashTable的区别 1 继承的父类不同 HashTable继承Dictionary类 而hashMap继承了AbstractMap类 但是二者都实现了map接口 2 线程安全性不同 Hashtable 线程安全 因为它
  • height:calc(100%-100px)如何兼容ie8

    做公司后台管理系统时 右边content main内容块高度出现了兼容问题 是content main包裹了iframe 如何兼容ie8 贴出以下代码部分 css js 原来css供参考 另一个参考地址 https stackoverflo
  • Ventoy的pe盘制作及重装系统步骤【解释的非常清楚!!!】

    文章目录 前言 正文 一 Ventoy的优点 二 Ventoy的pe盘制作 三 用Ventoy重装系统的过程 四 结尾 前言 当我们使用一般的pe盘的时候 他会把我们的u盘格式化 而且里面下载了很多文件 我们可能就不敢轻易的使用这个u盘作为
  • Netty中的那些坑

    转载自 http www cnblogs com rainy shurun p 5213086 html Netty中的那些坑 上篇 最近开发了一个纯异步的redis客户端 算是比较深入的使用了一把netty 在使用过程中一边优化 一边解决
  • 基于深度学习的图像去雾算法

    文章目录 前言 Preface 一 GFN dehazing 二 Dehaze cGAN 三 Cycle Dehaze 四 定性分析算法性能 Qualitative analysis of algorithm performance GFN
  • 计网第四章(网络层)(八)(最短路径优先协议OSPF)

    在第七节 计网第四章 网络层 七 永无魇足的博客 CSDN博客 我们总结了路由信息协议RIP 在最后我们提到了RIP协议有坏消息传的慢的问题 这是距离向量算法的本质决定的 所以这种问题无法彻底避免 既然基于距离向量无法彻底避免产生路由环路
  • numpy.argsort详解

    numpy argsort 用例 numpy argsort a axis 1 kind None order None 功能 返回数组排序后的元素索引值 根据kind指定的算法对数组沿着axis轴进行排序 其返回值的形状和a一致 返回值内
  • 干货 :深度学习必须掌握的 13 种概率分布

    来源 深度学习前沿 本文约1400字 建议阅读5分钟 这里有一份最常见的基本概率分布教程 大多数和使用 python 库进行深度学习有关 作为机器学习从业者 你需要知道概率分布相关的知识 这里有一份最常见的基本概率分布教程 大多数和使用 p
  • ZooKeeper 节点类型

    ZooKeeper 节点是有生命周期的 这取决于节点的类型 在 ZooKeeper 中 节点类型可以分为持久节点 PERSISTENT 临时节点 EPHEMERAL 以及时序节点 SEQUENTIAL 具体在节点创建过程中 一般是组合使用
  • 在mysql中删除数据后,添加数据,id值依然从删除的位置开始增加,问题详解。

    id name age email isActive 1 王老师 32 wangwc 163 com 1 2 王老师 32 wangwc 163 com 1 3 隔壁老王
  • Windows Server 2008 R2修改远程桌面连接数

    计算机 属性 远程设置 勾选 允许运行任意版本远程桌面的计算机连接 较不安全 第一步 开启远程桌面 计算机 属性 远程设置 勾选 允许运行任意版本远程桌面的计算机连接 较不安全 第二步 设置远程桌面连接最大数量 控制面板 gt 管理工具 g
  • 2020.11.12 算法练习

    2020 11 12 算法练习 题目描述 示例 算法思路 答案 运行示例 出现的问题 题目描述 给定一个非负整数数组 A A 中一半整数是奇数 一半整数是偶数 对数组进行排序 以便当 A i 为奇数时 i 也是奇数 当 A i 为偶数时 i
  • STM32简单呼吸灯的制作

    物联网应用技术2班 李俊运 20210320018 目的 实现呼吸灯 逐渐亮 逐渐灭 准备工作 1 首先我们需要准备32的最小系统板或者开发板 2 准备一个LED灯 如果使用板子上的灯来实现则不需要 下面我是使用最小系统板上的LED灯来实现
  • Datalore 安装使用教程

    发现一个jetbrain出的好东西 使用体验完爆jupyter notebook以及jupyter lab的软件 就是安装有点复杂 官网写得有点不清楚 这里简单介绍一下 首先他只能在linux运行 其他环境暂时不支持 首先 去https w
  • vscode内网环境部署

    1 首先需要一台能连网的电脑把需要的插件拷贝到内网电脑 把vscode传到内网电脑 在安装时选择环境变量 装完之后重启 2 安装Remote SSH 去官网下载 除了下载Remote SSH之外 还需要下载两个插件 Extensions f
  • 宝塔安装nextcloud

    首先买服务器 域名 ssl证书 最好开个子域名 比如 wangpan 666 com类似的 百度搜索宝塔 安装 就这样 装好之后打开宝塔 第一次安装环境的时候用lnmp 也就是nginx 注意php用7 0及以上版本 注意php装好之后选择
  • 【ssh】pycharm链接远程服务器出现:Bad owner or permissions on C:\\Users\\用户名/.ssh/config

    一直以来是用的pycharm 最近改用了vscode登录 并配置了config文件实现了vscode自动连接远程服务器 但是回到pycharm发现terminal端口不管用了 电脑上的powershell也是链接不上远程服务器并报错Bad
  • Unity TileMap 2D 工具基础教程

    Unity TileMap 2D 工具基础教程 Unity TileMap 2D 工具基础教程 TileMap 工程创建 Sprite Editor 工具使用 TileMap 功能说明 TilePalette 调色板功能 Unity Til
  • 网站安全狗

    phpstudy安装yxcms server2012安装phpstudy和网站安全狗 创建一个网站 将文件解压到phpstudy根目录下 访问网站进入安装页面 安装成功 windows服务器安装网站安全狗 启动apache服务 进行安装 安
  • WaterView 自定义圆形水波进度

    这几天不是很忙 完成了工作 利用闲暇的时间来完成一下以前不会玩的自定义动画 自定义圆形水波进度 这个以前把我难死了 死活不会 都怪自己太菜了 那么现在来看看到底难不难 真正最简单的实现方法 先来了解下path类的基本方法 移动起点 move