今天任老师发表了一篇关于Android5.0中按钮按下的波纹效果实现《Android L中水波纹点击效果的实现》,出于好奇我下载了源代码看了一下效果,正好手边有一个Nexus手机,我结合实际效果看了一下,发现有一些地方和实际效果稍有不同,参考任老师的博文实现简单实现了一个重写View组件的代码,将全部代码贴出,如果有什么问题或者更好的方式请指出,在此再次感谢任老师的这篇博文。

转载请说明出处:http://blog.csdn.net/dawanganban

顺便在这里拉一下票,如果你觉得这篇文章对你有所帮助,给阳光小强投一票吧:点击投票

主要改变的地方有:

1、在手指按下的时候会有两个变化,一个是在按钮上产生一个暗色全铺背景,然后再出现一个扩散的水波。

2、有长按和点击的区别,长按的时候水波是慢慢扩散,如果点击则会迅速扩散。

演示效果(这里暂时不贴图了,没有安装Android模拟器,动画效果录制不理想)

实现过程可以参考任老师的博文,并参考代码注释(注释的很详细,想必不难理解)

MyButton.java

package com.example.myreveallayout;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Android 5.0按钮点击效果
* 说明:可以将View替换成Button、ImageButton等组件。
* @author 阳光小强 http://blog.csdn.net/dawanganban
*
*/
public class MyButton extends View{ private static final int INVALIDATE_DURATION = 20; //每次刷新的时间间隔
private static int DIFFUSE_GAP = 10; //扩散半径增量
private static int TAP_TIMEOUT; //判断点击和长按的时间 private int viewWidth; //控件宽度和高度
private int viewHeight;
private int pointX; //控件原点坐标(左上角)
private int pointY;
private int maxRadio; //扩散的最大半径
private int shaderRadio; private Paint bottomPaint; //画笔
private Paint colorPaint; private boolean isPushButton; //记录是否按钮被按下 public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
TAP_TIMEOUT = ViewConfiguration.getLongPressTimeout();
} /**
* 初始化画笔资源
*/
private void initPaint() {
colorPaint = new Paint();
bottomPaint = new Paint();
colorPaint.setColor(getResources().getColor(R.color.reveal_color));
bottomPaint.setColor(getResources().getColor(R.color.bottom_color));
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.viewWidth = w;
this.viewHeight = h;
} private int eventX;
private int eventY;
private long downTime = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//只需要取一次时间
if(downTime == 0){
downTime = SystemClock.elapsedRealtime();
}
eventX = (int)event.getX();
eventY = (int)event.getY();
//计算最大半径
countMaxRadio();
isPushButton = true;
postInvalidateDelayed(INVALIDATE_DURATION);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if(SystemClock.elapsedRealtime() - downTime < TAP_TIMEOUT){
DIFFUSE_GAP = 30;
postInvalidate();
}else{
clearData();
}
break;
}
return true;
} /**
* 计算此时的最大半径
*/
private void countMaxRadio() {
if(viewWidth > viewHeight){
if(eventX < viewWidth / 2){
maxRadio = viewWidth - eventX;
}else{
maxRadio = viewWidth / 2 + eventX;
}
}else{
if(eventY < viewHeight / 2){
maxRadio = viewHeight - eventY;
}else{
maxRadio = viewHeight / 2 + eventY;
}
}
} /**
* 清理改变的数据(初始化数据)
*/
private void clearData(){
downTime = 0;
DIFFUSE_GAP = 10;
isPushButton = false;
shaderRadio = 0;
postInvalidate();
} @Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if(!isPushButton) return; //如果按钮没有被按下则返回 //绘制按下后的整个背景
canvas.drawRect(pointX, pointY, pointX + viewWidth, pointY + viewHeight, bottomPaint);
canvas.save();
//绘制扩散圆形背景
canvas.clipRect(pointX, pointY, pointX + viewWidth, pointY + viewHeight);
canvas.drawCircle(eventX, eventY, shaderRadio, colorPaint);
canvas.restore();
//直到半径等于最大半径
if(shaderRadio < maxRadio){
postInvalidateDelayed(INVALIDATE_DURATION,
pointX, pointY, pointX + viewWidth, pointY + viewHeight);
shaderRadio += DIFFUSE_GAP;
}else{
clearData();
}
}
}

完整源代码下载请点击右下角跳舞的小人,在群共享中可下载。

Android自定义组件系列【14】——Android5.0按钮波纹效果实现的更多相关文章

  1. Android自定义组件系列【7】——进阶实践(4)

    上一篇<Android自定义组件系列[6]--进阶实践(3)>中补充了关于Android中事件分发的过程知识,这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpan ...

  2. Android自定义组件系列【6】——进阶实践(3)

    上一篇<Android自定义组件系列[5]--进阶实践(2)>继续对任老师的<可下拉的PinnedHeaderExpandableListView的实现>进行了分析,这一篇计划 ...

  3. Android自定义组件系列【5】——进阶实践(2)

    上一篇<Android自定义组件系列[5]--进阶实践(1)>中对任老师的<可下拉的PinnedHeaderExpandableListView的实现>前一部分进行了实现,这一 ...

  4. Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动

    在上一篇文章<Android自定义组件系列[3]--自定义ViewGroup实现侧滑>中实现了仿Facebook和人人网的侧滑效果,这一篇我们将接着上一篇来实现双面滑动的效果. 1.布局示 ...

  5. Android自定义组件系列【3】——自定义ViewGroup实现侧滑

    有关自定义ViewGroup的文章已经很多了,我为什么写这篇文章,对于初学者或者对自定义组件比较生疏的朋友虽然可以拿来主义的用了,但是要一步一步的实现和了解其中的过程和原理才能真真脱离别人的代码,举一 ...

  6. Android5.0水波纹效果ripple实现

    1.如何设置波纹效果 // 波纹有边界 android:background="?android:attr/selectableItemBackground" // 波纹超出边界 ...

  7. Android自定义组件系列【1】——自定义View及ViewGroup

    View类是ViewGroup的父类,ViewGroup具有View的所有特性,ViewGroup主要用来充当View的容器,将其中的View作为自己孩子,并对其进行管理,当然孩子也可以是ViewGr ...

  8. Android自定义组件系列【13】——Android自定义对话框如此简单

    在我们的日常项目中很多地方会用到对话框,但是Android系统为我们提供的对话框样子和我们精心设计的界面很不协调,在这种情况下我们想很自由的定义对话框,或者有的时候我们的对话框是一个图片,没有标题和按 ...

  9. Android自定义组件系列【12】——非UI线程绘图SurfaceView

    一.SurfaceView的介绍 在前面我们已经会自定义View,使用canvas绘图,但是View的绘图机制存在一些缺陷. 1.View缺乏双缓冲机制. 2.程序必须重绘整个View上显示的图片,比 ...

随机推荐

  1. 紫书 习题 8-16 UVa 1618 (中途相遇法)

    暴力n的四次方, 然而可以用中途相遇法的思想, 分左边两个数和右边两个数来判断, 最后合起来判断. 一边是n平方logn, 合起来是n平方logn(枚举n平方, 二分logn) (1)两种比较方式是相 ...

  2. 题解 洛谷 P3381 【【模板】最小费用最大流】

    发了网络流,再来一发费用流 能做费用流的,网络流自然做得来,但在这还是不要脸的安利一下自己的博客(里面也有网络流的题解): 点我 扯远了... 费用流,就是在不炸水管的情况下求源点到汇点的最小费用. ...

  3. CSDN 轻松周赛赛题:能否被8整除

    轻松周赛赛题:能否被8整除 题目详情 给定一个非负整数,问能否重排它的全部数字,使得重排后的数能被8整除. 输入格式: 多组数据,每组数据是一个非负整数.非负整数的位数不超过10000位. 输出格式 ...

  4. ZOJ 3365 Integer Numbers

    Integer Numbers Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on ZJU. Origina ...

  5. hadoop-13-root ssh无密码登陆

    hadoop-13-root ssh无密码登陆 生产机器禁止ROOT远程SSH登录: vi /etc/ssh/sshd_config 把 PermitRootLogin yes 改为 PermitRo ...

  6. hdoj Let the Balloon Rise

     /*Let the Balloon Rise Problem Description Contest time again! How excited it is to see balloons ...

  7. Unity 相机花式分屏

    花式分屏,顾名思义,可以实现各种不规则几何边界的分屏,是无法直接通过调整相机视口能达到效果的(只能实现矩形的分屏),例如斜对角分屏,几何图形分屏: 假设我们有两个相机,需要上面的斜对角分屏画面,和镜子 ...

  8. BsonDocument

    http://api.mongodb.com/csharp/current/html/T_MongoDB_Bson_BsonDocument.htm 如何取出document中的数据 BsonDocu ...

  9. linux下修改完profile文件的环境变量后如何立即生效

    方法1: 让/etc/profile文件修改后立即生效 ,可以使用如下命令: # . /etc/profile 注意: . 和 /etc/profile 有空格 方法2: 让/etc/profile文 ...

  10. 关于docker部署javaweb应用的问题

    我做了两个镜像,一个mysql,一个tomcat.建完mysql容器之后,在建tomcat的时候用--link把他们链接起来了进tomcat的容器里面 /etc/hosts 也发现了mysql的ip但 ...