今天任老师发表了一篇关于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(); } } }完整 源代码下载请 点击右下角跳舞的小人,在群共享中可下载。