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();
}
}
}
完整源代码下载请点击右下角跳舞的小人,在群共享中可下载。
Android自定义组件系列【14】——Android5.0按钮波纹效果实现的更多相关文章
- Android自定义组件系列【7】——进阶实践(4)
上一篇<Android自定义组件系列[6]--进阶实践(3)>中补充了关于Android中事件分发的过程知识,这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpan ...
- Android自定义组件系列【6】——进阶实践(3)
上一篇<Android自定义组件系列[5]--进阶实践(2)>继续对任老师的<可下拉的PinnedHeaderExpandableListView的实现>进行了分析,这一篇计划 ...
- Android自定义组件系列【5】——进阶实践(2)
上一篇<Android自定义组件系列[5]--进阶实践(1)>中对任老师的<可下拉的PinnedHeaderExpandableListView的实现>前一部分进行了实现,这一 ...
- Android自定义组件系列【4】——自定义ViewGroup实现双侧滑动
在上一篇文章<Android自定义组件系列[3]--自定义ViewGroup实现侧滑>中实现了仿Facebook和人人网的侧滑效果,这一篇我们将接着上一篇来实现双面滑动的效果. 1.布局示 ...
- Android自定义组件系列【3】——自定义ViewGroup实现侧滑
有关自定义ViewGroup的文章已经很多了,我为什么写这篇文章,对于初学者或者对自定义组件比较生疏的朋友虽然可以拿来主义的用了,但是要一步一步的实现和了解其中的过程和原理才能真真脱离别人的代码,举一 ...
- Android5.0水波纹效果ripple实现
1.如何设置波纹效果 // 波纹有边界 android:background="?android:attr/selectableItemBackground" // 波纹超出边界 ...
- Android自定义组件系列【1】——自定义View及ViewGroup
View类是ViewGroup的父类,ViewGroup具有View的所有特性,ViewGroup主要用来充当View的容器,将其中的View作为自己孩子,并对其进行管理,当然孩子也可以是ViewGr ...
- Android自定义组件系列【13】——Android自定义对话框如此简单
在我们的日常项目中很多地方会用到对话框,但是Android系统为我们提供的对话框样子和我们精心设计的界面很不协调,在这种情况下我们想很自由的定义对话框,或者有的时候我们的对话框是一个图片,没有标题和按 ...
- Android自定义组件系列【12】——非UI线程绘图SurfaceView
一.SurfaceView的介绍 在前面我们已经会自定义View,使用canvas绘图,但是View的绘图机制存在一些缺陷. 1.View缺乏双缓冲机制. 2.程序必须重绘整个View上显示的图片,比 ...
随机推荐
- 【BZOJ 1212】[HNOI2004]L语言
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 因为查询的字典里面.单词的最大长度为10 所以. 如果建立一棵字典树的话. 深度最多为10: 那么可以写一个DP; 设f[i]表示1 ...
- [Angular] Create a ng-true-value and ng-false-value in Angular by controlValueAccessor
If you're coming from AngularJS (v1.x) you probably remember the ng-true-value and ng-false-value di ...
- Android中设置半个屏幕大小且居中的button布局 (layout_weight属性)
先看例如以下布局 :
- Unity渲染
我们先大概了解一下对渲染的优先级有影响的几个因素 1.Camera.Depth 不同相机的深度,在渲染顺序的优先度里面是最高的,Depth越大,渲染的图像越靠前 2.Render.SortingOrd ...
- 在Linux的终端中显示BMPString的内容
在上一篇博文中,介绍了怎样在 Windows 的控制台界面下输出 BMPString 的内容,可是那里的方法在 Linux 下不适用.假设将那里的演示样例代码放到 Linux 下运行.输出的结果为乱码 ...
- 浅析为什么 char 类型的范围是 : -128~+127
在 C 语言中. signed char 类型的范围为 -128~127,每本教科书上也这么写.可是没有哪一本书上(包含老师)也不会给你为什么是 -128~127,这个问题貌似看起来也非常easyea ...
- [ACM] HDU 1400 Mondriaan's Dream (状态压缩,长2宽1长方形铺满)
Mondriaan's Dream Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- CodeForces 550B Preparing Olympiad(DFS回溯+暴力枚举)
[题目链接]:click here~~ [题目大意] 一组题目的数目(n<=15),每一个题目有对应的难度,问你选择一定的题目(大于r个且小于l个)且选择后的题目里最小难度与最大难度差不小于x, ...
- js html 事件冒泡
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- Nginx搭建图片服务器
Nginx搭建图片服务器 标签(空格分隔): linux,nginx Nginx常用命令 ./nginx 启动 ./nginx -s reload 重载配置文件 ./nginx -s stop|sta ...