zoukankan      html  css  js  c++  java
  • Android自定义组件系列【14】——Android5.0按钮波纹效果实现

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

  • 相关阅读:
    python邮件之附件
    python3.5之smtp
    一台Linux上搭建两个tomcat
    mysql 初探(一)
    python监视mysql最大连接数
    P3658 [USACO17FEB]Why Did the Cow Cross the Road III P cdq分治
    P4793 [AHOI2008]矩形藏宝地 cdq分治 线段树
    P2487 [SDOI2011]拦截导弹 线段树 cdq分治
    P3157 [CQOI2011]动态逆序对 cdq分治
    P4169 [Violet]天使玩偶/SJY摆棋子 cdq分治
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468552.html
Copyright © 2011-2022 走看看