android 按钮颤动效果,Android自定义组件系列Android5.0按钮波纹效果实现

释放双眼,带上耳机,听听看~!

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

主要改变的地方有:

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();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值