/**

* 控件的点击动画

*/

public class AnimClickUtil {

//动画执行速度

public final int ANIM_SPEED = 300;

//旋转角度

private final float POTATION_VALUE = 7f;

//变速器

public OvershootInterpolator interpolator = new OvershootInterpolator(3f);

//缩放比例

private final float SCALE_END = 0.8f;

//阴影最小值

private final float SHADOW_END = 0;

private boolean isClick; //标识点击是否有效,有效执行回掉,否则只执行动画

/**

* 启动按压动画

*

* @param view 执行动画的View

* @param superb 效果类型【true:华丽效果】【false:缩放效果】

* @param x 触点X坐标

* @param y 触点Y坐标

* @return 动画执行顶点

*/

public int startAnimDown(View view, boolean superb, float x, float y) {

if (false == view.isClickable()) {

return 1;

}

int pivot;

// 缩放效果

if (false == superb) {

pivot = 0;

// 执行缩小动画【缩放效果】

froBig_ToSmall(view);

return pivot;

}

// 华丽效果

int w = view.getWidth();

int h = view.getHeight();

if ((w / 5 * 2) < x && x < (w / 5 * 3) && (h / 5 * 2) < y && y < (h / 5 * 3)) {

pivot = 0;

} else if (x < w / 2 && y < h / 2) { // 第一象限

if (x / (w / 2) > y / (h / 2)) {

pivot = 1;

} else {

pivot = 4;

}

} else if (x < w / 2 && y >= h / 2) { // 第四象限

if ((w - x) / (w / 2) > y / (h / 2)) {

pivot = 4;

} else {

pivot = 3;

}

} else if (x >= w / 2 && y >= h / 2) { // 第三象限

if ((w - x) / (w / 2) > (h - y) / (h / 2)) {

pivot = 3;

} else {

pivot = 2;

}

} else { // 第二象限

if (x / (w / 2) > (h - y) / (h / 2)) {

pivot = 2;

} else {

pivot = 1;

}

}

String anim = "";

switch (pivot) {

case 0:

view.setPivotX(w / 2);

view.setPivotY(h / 2);

// 执行缩小动画【缩放效果】

froBig_ToSmall(view);

return pivot;

case 1:

case 3:

anim = "rotationX";

break;

case 2:

case 4:

anim = "rotationY";

break;

default:

break;

}

view.setPivotX(w / 2);

view.setPivotY(h / 2);

// 执行缩小动画【华丽效果】

froBig_ToSmall(view, pivot, anim);

return pivot;

}

/**

* 启动抬起动画

*

* @param view 执行动画的View

* @param pivot 动画执行顶点

*/

public void startAnimUp(View view, int pivot,boolean isClick) {

this.isClick = isClick;

if (false == view.isClickable()) {

return;

}

if (pivot == 0) {

// 执行放大动画【缩放效果】

froSmall_ToBig(view);

} else {

String anim = "";

switch (pivot) {

case 1:

case 3:

anim = "rotationX";

break;

case 2:

case 4:

anim = "rotationY";

break;

}

// 执行放大动画【华丽效果】

froSmall_ToBig(view, pivot, anim);

}

}

/**

* 【华丽效果】从大过渡到小

*/

private void froBig_ToSmall(View view, int pivot, String anim) {

float potationEnd;

if (pivot == 3 || pivot == 4) {

potationEnd = 0 - POTATION_VALUE;

} else {

potationEnd = POTATION_VALUE;

}

int potationStart = 0;

if (pivot == 2 || pivot == 4) {

potationStart = (int) view.getRotationY();

} else {

potationStart = (int) view.getRotationX();

}

ObjectAnimator animObject = ObjectAnimator.ofFloat(view, anim, potationStart, potationEnd)

.setDuration(ANIM_SPEED);

animObject.setInterpolator(interpolator);

animObject.start();

}

/**

* 【华丽效果】从小过渡到大

*/

private void froSmall_ToBig(View view, int pivot, String anim) {

int potation;

if (pivot == 2 || pivot == 4) {

potation = (int) view.getRotationY();

} else {

potation = (int) view.getRotationX();

}

ObjectAnimator animObject = ObjectAnimator.ofFloat(view, anim, potation, 0).setDuration(ANIM_SPEED);

animObject.setInterpolator(interpolator);

animObject.start();

}

/**

* 【缩放效果】从大过渡到小

*/

public void froBig_ToSmall(View view) {

try {

float tzStart = 0;

Object viewTag = view.getTag(R.string.anim_click_tag_key_translation_z);

if (android.os.Build.VERSION.SDK_INT >= 21) {

tzStart = view.getTranslationZ();

if (viewTag == null || false == viewTag instanceof Float) {

view.setTag(R.string.anim_click_tag_key_translation_z, tzStart);

}

}

//控件的长宽高执行缩小动画

PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, SHADOW_END);

PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX", view.getScaleX(), SCALE_END);

PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY", view.getScaleY(), SCALE_END);

ObjectAnimator animatorD = ObjectAnimator.ofPropertyValuesHolder(view, tz, sx, sy).setDuration(ANIM_SPEED);

animatorD.setInterpolator(interpolator);

animatorD.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

//动画结束时的回掉

if (listener1 != null && isClick) {

listener1.onDownEnd();

}

}

});

animatorD.start();

} catch (Exception e) {

}

}

/**

* 【缩放效果】从小过渡到大

*/

public void froSmall_ToBig(View view) {

try {

float tzStart = 0, tzEnd = 0;

Object viewTag = view.getTag(R.string.anim_click_tag_key_translation_z);

if (android.os.Build.VERSION.SDK_INT >= 21) {

tzStart = view.getTranslationZ();

if (viewTag != null && viewTag instanceof Float) {

tzEnd = (Float) viewTag;

}

}

//控件的长宽高执行缩小后的恢复动画

PropertyValuesHolder tz = PropertyValuesHolder.ofFloat("translationZ", tzStart, tzEnd);

PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX", view.getScaleX(), 1);

PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY", view.getScaleY(), 1);

ObjectAnimator animatorD = ObjectAnimator.ofPropertyValuesHolder(view, tz, sx, sy).setDuration(ANIM_SPEED);

animatorD.setInterpolator(interpolator);

animatorD.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

//动画结束时的回掉

if (listener1 != null && isClick) {

listener1.onUpEnd();

}

}

});

animatorD.start();

} catch (Exception e) {

}

}

public interface OnAnimEndListener {

void onDownEnd();

void onUpEnd();

}

public OnAnimEndListener listener1;

public void setAnimEndListener(OnAnimEndListener listener) {

listener1 = listener;

}

}

/***

* 只要控件外层套上该控件,即可实现点击动画

*/

public class AnimRelativeLayout extends RelativeLayout {

/**

* 动画模式【true:华丽效果——缩放加方向】【false:只缩放】

* 华丽效果:即点击控件的 上、下、左、右、中间时的效果都不一样

* 普通效果:即点击控件的任意部位,都只是缩放效果,与 华丽效果模式下 点击控件中间时的动画一样

**/

private boolean superb = false;

/**

* 顶点判断【0:中间】【1:上】【2:右】【3:下】【4:左】

**/

private int pivot = 0;

private AnimClickUtil bamAnim;

public AnimRelativeLayout(Context context) {

this(context,null);

this.setClickable(true);

}

public AnimRelativeLayout(Context context, AttributeSet attrs) {

this(context, attrs,0);

this.setClickable(true);

}

public AnimRelativeLayout(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

this.setClickable(true);

initView();

}

private void initView() {

bamAnim = new AnimClickUtil();

}

/**

* 打开/关闭华丽效果,默认时关闭的

*/

public void openSuperb(boolean isOpen) {

superb = isOpen;

}

@Override

@SuppressLint("ClickableViewAccessibility")

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

pivot = bamAnim.startAnimDown(this, superb, event.getX(), event.getY());

break;

case MotionEvent.ACTION_CANCEL:

bamAnim.startAnimUp(this, pivot,false);

break;

case MotionEvent.ACTION_UP:

bamAnim.startAnimUp(this, pivot,true);

break;

default:

break;

}

return super.onTouchEvent(event);

}

public void setDownEndListener(AnimClickUtil.OnAnimEndListener listener) {

bamAnim.setAnimEndListener(listener);

}

使用方式:直接在外层嵌套Layout即可。

效果如下:

android点击特效,android 点击特效动画相关推荐

  1. android特效按钮点击效果

    2019独角兽企业重金招聘Python工程师标准>>> android特效按钮点击效果,动画从里到外渐变放大散花效果,本例子适合做一些特效的app使用, 使用很简单,直接可以把里面代 ...

  2. android qq右上加号,仿QQ空间点击加号弹出菜单特效

    最近项目需要,前几天写了一个仿微信相册(包括编辑相册)功能,审核代码的时候发现同事要实现一个类似仿QQ空间点击加号弹出菜单特效,于是看了一些他的代码,我发现虽然他实现了功能,但是不够完善,所以我又花了 ...

  3. android 自定义特效,Android自定义FloatingText仿点赞+1特效

    本文实例为大家分享了Android自定义View,可以仿点赞往上飘+1的一个特效,或者点击加入购物车商品抛物线特效. FloatingText 是一个能够在任何控件之上执行漂浮效果动画的控件. 效果图 ...

  4. android怎么用代码调图像,浅谈android中图片处理之图形变换特效Matrix(四)(示例代码)...

    今天,我们就来谈下android中图片的变形的特效,在上讲博客中我们谈到android中图片中的色彩特效来实现的.改变它的颜色主要通过ColorMatrix类来实现. 现在今天所讲的图片变形的特效主要 ...

  5. 浅谈android中图片处理之图形变换特效Matrix(四)

    今天,我们就来谈下android中图片的变形的特效,在上讲博客中我们谈到android中图片中的色彩特效来实现的.改变它的颜色主要通过ColorMatrix类来实现. 现在今天所讲的图片变形的特效主要 ...

  6. android xml红心圆,用android:clipChildren来实现红心变大特效

    最近在看别人技术博客(http://www.cnblogs.com/over140/p/3508335.html)的时候,发现一个属性:android:clipChildren属性. 翻文档找到下面介 ...

  7. Android修行手册-Button实现点击音效有多简单?

    下了手中的武器,我知道你已厌倦,目送你离开,亮起黄昏的路灯,照亮你回家的路. 往期文章分享 点击跳转=>熬夜再战Android从青铜到王者-开发效率插件篇 点击跳转=>Unity粒子特效系 ...

  8. Android Splash界面支持用户点击 直接进入主界面

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/23613403 现在大部分APP都有Splash界面,下面列一下Splash页面的 ...

  9. android relativelayout 点击事件,Android Relativelayout点击背景行为

    所以我有一个RecyclerView,它是由我的自定义布局(代码如下)填充.我制作了一个可绘制的背景,并将其设置在我的自定义布局的根部,以便用户单击该项目时,背景颜色会发生变化.每个项目的布局上还有一 ...

  10. android切换字体颜色,Android开发实现按钮点击切换背景并修改文字颜色的方法

    本文实例讲述了Android开发实现按钮点击切换背景并修改文字颜色的方法.分享给大家供大家参考,具体如下: 其实原理很简单,用到的是selector,用来设置android:background和an ...

最新文章

  1. 利用歌词插件 让WMP活起来
  2. Linux C++与Python混合编程(g++生成链接库与python调用)
  3. 【ES6】变量的解构赋值
  4. bash魔法堂:History用法详解
  5. GO语言变量和常量、语言控制语句流程
  6. python语法详解大全_笔记:Python 语法要点汇总
  7. Android SDK打包
  8. python kotlin_Java和Python中类似Kotlin的生成器,续:附加参数
  9. polkit 重新安装_不折腾,为U-NAS安装一个清爽的桌面,把小U打造成双面高手
  10. mogndb 慢查询
  11. 本地apk安装是什么意思_Sony电视安装第三方播放器
  12. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感...
  13. 极域电子教室功能讲解-电子教室
  14. Matlab中sqrt函数的用法
  15. 服务器被攻击显示,怎么查看服务器被攻击
  16. (2/2) sharex录制屏幕没有声音,升级高版本的 sharex
  17. 移远EC20--1 AT命令初始2
  18. 低压差稳压器--AMS1117芯片简介 结构
  19. Getter和Setter的介绍
  20. 二年级上册计算题_分享14套二年级数学乘法计算题

热门文章

  1. pandas学习之变形
  2. msm 8953 camera 流程
  3. 一阶电路实验报告心得_实验九实验报告(二)--一阶动态电路的响应测试
  4. delphi android 打印机,delphi中如何检测打印机状态?(在线等) ( 积分: 100 )
  5. ubuntu 拷贝文件夹下所有文件到其他文件夹操作
  6. 数字图像处理 信息隐藏 LSB算法
  7. 基础LSB算法的matlab实现
  8. Linux如何磁盘分区
  9. VTN联合GWI共同启动“全球健康登月计划”让更多人享受到健康新生活
  10. 头像/证件照抠图与圣诞背景替换