Android自定义View——实现水波纹效果类似剩余流量球

最近突然手痒就想搞个贝塞尔曲线做个水波纹效果玩玩,终于功夫不负有心人最后实现了想要的效果,一起来看下吧:

效果图镇楼

一:先一步一步来分解一下实现的过程

  1. 需要绘制一个正弦曲线(sin)或者余弦曲线(cos)
  2. 通过水平平移曲线来的到像水波波动的效果
  3. 水平移动的同时还需要有水位上涨,也就是向上平移
  4. 裁剪画布为圆形,在圆形区域绘制曲线
  5. 通过上面4步就可以实现了

二:现在就来实现第一步,绘制一个sin曲线;这里画了一张图来帮助理解,在PhotoShop中我们绘制一个贝塞尔曲线可以清楚的看到它的控制点如图:

     

???绘制贝塞尔曲线我们必须要知道三个点:起点、控制点、终点;有了这三个点我们就可以绘制一段简单二阶贝塞尔曲线。从图中我们可以看出 起点 控制点p1 x1 这三个点绘制了一段曲线,也就是通过path.quadTo()函数添加一个曲线路径。 
???假设我们需要绘制一个周期的sin曲线,那么我们就只需要知道起点、一个周期的宽度、振幅;就可以绘制一个sin曲线了。

三:下面就来看下代码的实际操作了,这里就直接省略掉一些画笔初始化的操作了可以点击这里查看源码

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //获取view的宽度
    width = getViewSize(800, widthMeasureSpec);
    //获取view的高度
    height = getViewSize(400, heightMeasureSpec);
    //获取起点坐标
    startPoint = new Point(0, height / 2);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

首先肯定是要获取到画布的大小才能确定好起点的坐标,有了起点坐标就可以开始绘制我们的曲线了

在ondraw()函数中进行曲线的绘制

/*sin曲线 1/4个周期的宽度*/
private int cycle = 200;
/*sin曲线振幅的高度*/
private int waveHeight = 200;

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    path.moveTo(startPoint.x, startPoint.y);
    int j = 1;
    //循环绘制正弦曲线 循环一次半个周期
    for (int i = 1; i <= 8; i++) {
        if (i % 2 == 0) {
        //波峰
            path.quadTo(startPoint.x + (cycle * j), startPoint.y + waveHeight,
                    startPoint.x + (cycle * 2) * i, startPoint.y);
        } else {
        //波谷
            path.quadTo(startPoint.x + (cycle * j), startPoint.y - waveHeight,
                    startPoint.x + (cycle * 2) * i, startPoint.y);
        }
        j += 2;
    }
    //绘制封闭的曲线
    path.lineTo(width, height);//右下角
    path.lineTo(startPoint.x, height);//左下角
    path.lineTo(startPoint.x, startPoint.y);//起点
    path.close();
    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

经过上面一系例操作一个水波纹效果就出来啦

四:接下来就是水平移动这个曲线了为了移动起来更加好看,我们需要在屏幕外面开始绘制一个周期,如下:

//初始化的时候将起点移至屏幕外一个周期
startPoint = new Point(-cycle * 4, height / 2);

//继续在ondraw()函数最后追加平移代码

//判断是不是平移完了一个周期
if (startPoint.x + 40 >= 0) {
    //满了一个周期则恢复默认起点继续平移
    startPoint.x = -cycle * 4;
}
//每次波形的平移量 40
startPoint.x += 40;
postInvalidateDelayed(150);
path.reset();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

只需要这样就可以产生水波效果了,一起来看效果图吧。

五:接下来就是要将画布变成圆形了(其实还是个矩形,只是绘画区域在你所裁剪的区域),然后在里面实现水波纹就哦的K了;完整的绘制代码如下:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //裁剪画布为圆形
    Path circlePath = new Path();
    circlePath.addCircle(width / 2, height / 2, width / 2, Path.Direction.CW);
    canvas.clipPath(circlePath);
    canvas.drawPaint(circlePaint);
    canvas.drawCircle(width / 2, height / 2, width / 2, circlePaint);
    //以下操作都是在这个圆形画布中操作
    //根据进度改变起点坐标的y值
    startPoint.y = (int) (height - (progress / 100.0 * height));
    //起点
    path.moveTo(startPoint.x, startPoint.y);
    int j = 1;
    //循环绘制正弦曲线 循环一次半个周期
    for (int i = 1; i <= 8; i++) {
        if (i % 2 == 0) {
            path.quadTo(startPoint.x + (cycle * j), startPoint.y + waveHeight,
                    startPoint.x + (cycle * 2) * i, startPoint.y);
        } else {
            path.quadTo(startPoint.x + (cycle * j), startPoint.y - waveHeight,
                    startPoint.x + (cycle * 2) * i, startPoint.y);
        }
        j += 2;
    }
    //绘制封闭的曲线
    path.lineTo(width, height);//右下角
    path.lineTo(startPoint.x, height);//左下角
    path.lineTo(startPoint.x, startPoint.y);//起点
    path.close();
    canvas.drawPath(path, paint);
    drawText(canvas, textPaint, progress + "%");
    //判断是不是平移完了一个周期
    if (startPoint.x + 40 >= 0) {
        //满了一个周期则恢复默认起点继续平移
        startPoint.x = -cycle * 4;
    }
    //每次波形的平移量 40
    startPoint.x += 40;
    if (autoIncrement) {
        if (progress >= 100) {
            progress = 0;
        } else {
            progress++;
        }
    }
    postInvalidateDelayed(150);
    path.reset();
}
时间: 2024-10-10 16:57:10

Android自定义View——实现水波纹效果类似剩余流量球的相关文章

Android 自定义view实现水波纹效果

http://blog.csdn.net/tianjian4592/article/details/44222565 在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她: 在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢: 好了,为了让大家都能给妹纸们想要的,后面会逐渐分享一些比较比较不错的效果,目的只有一个,通过自定义view实现我们所能实现的动效: 今天主要分

自定义view实现水波纹效果

今天看到一篇自定view 实现水波纹效果 觉得真心不错 学习之后再次写下笔记和心得.但是感觉原作者写得有些晦涩难懂,也许是本人愚笨 所以重写此作者教程.原作者博文大家可以去看下,感觉他在自定义view方面非常厉害,本文是基于此作者原文重新改写,拥有大量像相似部分 先看下效果吧: 1. 效果1: 2. 效果2 我先们来学习效果1: 效果1实现本质:用一张波形图和一个圆形图的图片,然后圆形图在波形图上方,然后使用安卓的图片遮罩模式desIn(不懂?那么先记住有这样一个遮罩模式).(只显示上部图像和下

[转]Android自定义控件系列五:自定义绚丽水波纹效果

出处:http://www.2cto.com/kf/201411/353169.html 今天我们来利用Android自定义控件实现一个比较有趣的效果:滑动水波纹.先来看看最终效果图: 图一 效果还是很炫的:饭要一口口吃,路要一步步走,这里我们将整个过程分成几步来实现 一.实现单击出现水波纹单圈效果: 图二 照例来说,还是一个自定义控件,这里我们直接让这个控件撑满整个屏幕(对自定义控件不熟悉的可以参看我之前的一篇文章:Android自定义控件系列二:自定义开关按钮(一)).观察这个效果,发现应该

Android自定义控件系列五:自定义绚丽水波纹效果

尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自定义控件实现一个比较有趣的效果:滑动水波纹.先来看看最终效果图: 图一 效果还是很炫的:饭要一口口吃,路要一步步走,这里我们将整个过程分成几步来实现 一.实现单击出现水波纹单圈效果: 图二 照例来说,还是一个自定义控件,这里我们直接让这个控件撑满整个屏幕(对自定义控件不熟悉的可以参看我之前的一篇文章:Android自定义控件系列二

Android自定义控件-Path之贝赛尔曲线和手势轨迹、水波纹效果

从这篇开始,我将延续androidGraphics系列文章把图片相关的知识给大家讲完,这一篇先稍微进阶一下,给大家把<android Graphics(二):路径及文字>略去的quadTo(二阶贝塞尔)函数,给大家补充一下. 本篇最终将以两个例子给大家演示贝塞尔曲线的强大用途: 1.手势轨迹 利用贝塞尔曲线,我们能实现平滑的手势轨迹效果 2.水波纹效果 电池充电时,有些手机会显示水波纹效果,就是这样做出来的. 废话不多说,开整吧 一.概述 在<android Graphics(二):路径

Android特效专辑(十)——点击水波纹效果实现,逻辑清晰实现简单

Android特效专辑(十)--点击水波纹效果实现,逻辑清晰实现简单 这次做的东西呢,和上篇有点类似,就是用比较简单的逻辑思路去实现一些比较好玩的特效,最近也是比较忙,所以博客更新的速度还得看时间去推演,但是也能保证一周三更的样子,现在也还是以小功能,或者说是一些小入门级别的博客为主,我也不算是什么很厉害的人,很多细节的支持处理的仍然还是不到位,所以也是一直在弥补,话不多说,来看看今天的效果 实现起来很简单吧,那我们就来看一下他是怎么实现的咯! OnclickRuning package com

Android Ripple 按钮水波纹效果(二)优化

上一篇中我们讲了自定义ripple 水波纹效果,先来回顾一下效果吧! 看了以后感觉没甚么问题,我一开始也觉得很满意了,那好,我们拿Android 5.0自带的效果来对比一下 发现了不同之处没?点击中间的时候是看不出什么区别,但是点击两边的时候,就很明显了,我们自定义的效果,波纹向两边同速度的扩散,所以就会出现,如果点击点不在中心的时候,距离短的一边波纹先到达,而距离长的一边后到达,不能同时到达边缘!而系统自带的则不存在这种情况,所以这是一个优化点;另一个优化点是:我们自定义的效果,在波纹全部覆盖

Android 实现RippleEffect水波纹效果

最近看到360.UC.网易新闻客户端都应用了水波纹效果,就在私下里也研究了一下,参照GIT上大神的分享,自己也跟着做了一个示例,下面先看效果: 1.RippleEffect核心实现类 package com.example.RippleEffect; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphi

Android 颜色渲染(七) RadialGradient 环形渲染实现水波纹效果

版权声明:本文为博主原创文章,未经博主允许不得转载. 利用环形渲染我们可以做到什么? 其实很多都是非常常见的,比如上一篇实现的帮帮糖效果, 彩色的热气球,比如这里要讲到的水波纹效果,或者也可以理解为扩散色渲染效果 首先看一下效果图: 轻触屏幕,即可看到对应的效果,可以看到,实现这种效果,利用RadialGradient ,只需简单几行代码: MainActivity: [java] view plain copy package com.tony.testshader; import andro