思路
通过监听onTouch
方法
- 在
MotionEvent.ACTION_DOWN
执行view变小的动画
v.animate().scaleX(scale).scaleY(scale).setDuration(duration).setInterpolator(interpolator);
- 在
MotionEvent.ACTION_CANCEL
和MotionEvent.ACTION_UP
时执行还原的动画
v.animate().scaleX(1).scaleY(1).setInterpolator(interpolator);
- 同时需要注意在
onTouch
方法return true;
及处理VIEW的pressed state
核心代码
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
v.animate().scaleX(scale).scaleY(scale).setDuration(duration).setInterpolator(interpolator);
v.setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
boolean isInside = (x > 0 && x < v.getWidth() && y > 0 && y < v.getHeight());
if (v.isPressed() != isInside) {
v.setPressed(isInside);
}
break;
case MotionEvent.ACTION_CANCEL:
v.setPressed(false);
v.animate().scaleX(1).scaleY(1).setInterpolator(interpolator);
break;
case MotionEvent.ACTION_UP:
v.animate().scaleX(1).scaleY(1).setInterpolator(interpolator);
if (v.isPressed()) {
v.performClick();
v.setPressed(false);
}
break;
}
return true;
}
调用方法
ImageView iv = (ImageView) findViewById(R.id.iv_test);
TextView tv = (TextView) findViewById(R.id.tv_test);
OnClickAnimTouchListener clickAnim = new OnClickAnimTouchListener();
iv.setOnTouchListener(clickAnim);
tv.setOnTouchListener(clickAnim);
update: 2016.01.15 做了下重构,顺便把代码迁移到我自己的Lib工程,并上传Jcenter以便以后使用
- 把效果部分抽取成一个接口
public interface ViewClickEffect {
/** * 按下去的效果 */
void onPressedEffect(View view);
/** * 释放的效果 * @param view */
void onUnPressedEffect(View view);}
- 这样我们之前实现的放大缩小效果就变成了 完整代码
@Override
public void onPressedEffect(View view) {
view.animate().scaleX(scale).scaleY(scale).setDuration(duration).setInterpolator(interpolator);
}
@Overridepublic void onUnPressedEffect(View view) {
view.animate().scaleX(1).scaleY(1).setInterpolator(interpolator);
}
再顺手写一个点击时改变透明度的 完整代码
@Override
public void onPressedEffect(View view) {
view.animate().alpha(scale).setDuration(duration).setInterpolator(interpolator);
}
@Override
public void onUnPressedEffect(View view) {
view.animate().alpha(1).setDuration(duration).setInterpolator(interpolator);
}
- 这时候我们在
OnClickEffectTouchListener
:)改个了名捏 里面增加一个变量,外部可以传ViewClickEffect
接口的实现,或者以上两个默认实现
private ViewClickEffect mViewClickEffect = new DefaultClickEffectScaleAnimate();
public void setViewClickEffect(ViewClickEffect viewClickEffect) {
mViewClickEffect = viewClickEffect;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mViewClickEffect.onPressedEffect(v);
v.setPressed(true);
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
boolean isInside = (x > 0 && x < v.getWidth() && y > 0 && y < v.getHeight());
if (v.isPressed() != isInside) {
v.setPressed(isInside);
}
break;
case MotionEvent.ACTION_CANCEL:
mViewClickEffect.onUnPressedEffect(v);
v.setPressed(false);
break;
case MotionEvent.ACTION_UP:
mViewClickEffect.onUnPressedEffect(v);
if (v.isPressed()) {
v.performClick();
v.setPressed(false);
}
break;
}
return true;
}
update: 2016.02.19 发现这边设置后会屏蔽长按事件,如果需要响应长按事件的请先不要用此方法,后面有时间再看如何解决。
是不是很简单没啥技术含量呢,如果喷,请轻喷
完整代码 GitHub
网友评论