Skip to content

Instantly share code, notes, and snippets.

@SachinR90
Created October 5, 2017 11:58
Show Gist options
  • Save SachinR90/00536fda826e9286faaf30126085853b to your computer and use it in GitHub Desktop.
Save SachinR90/00536fda826e9286faaf30126085853b to your computer and use it in GitHub Desktop.
CustomOnTouchListener
import android.os.SystemClock;
import android.support.animation.DynamicAnimation;
import android.support.animation.SpringAnimation;
import android.support.animation.SpringForce;
import android.view.MotionEvent;
import android.view.View;
import java.lang.ref.SoftReference;
/**
* <p>
* This class is used to set a touch listener to a View object, which helps to listen to touch events.<br/>
* when user clicks any view having this touch listener, we create a bounce effect animation on that view.<br/>
* This can be used on any view.<br>
* This class is dependant on DynamicAnimationLibrary from google. So please add the library to gradle .<br><br>
* <b>compile 'com.android.support:support-dynamic-animation:25.3.1'</b>
* </p>
*/
public class CustomOnTouchListener implements View.OnTouchListener {
/**
* the view's Initial Scale
*/
private static final float INITIAL_SCALE = 1f;
/**
* this is used to handle the lastClickTime to avoid multi simultaneous taps and clicks
*/
private long mLastClickTime;
/**
* We need to scale the x property of view
*/
private SpringAnimation animationX;
/**
* we need to scale the y property of the view
*/
private SpringAnimation animationY;
/**
* Listener to listen to Animation end of the Spring animation
*/
private AnimationEndListener mEndListener;
@Override
public boolean onTouch(View v, MotionEvent event) {
//when user has caused Action_Up event
if (event.getAction() == MotionEvent.ACTION_UP) {
//check if system elapsed (milliseconds - lastClick) time > LAST_CLICK_TIME
if (SystemClock.elapsedRealtime() - mLastClickTime > 500) {//save last click time
if (animationX == null) { // check if animation x is null... create new animation if null
animationX = createAnimation(v, SpringAnimation.SCALE_X);
}
if (animationY == null) {// check if animation is null... create new animation if null
animationY = createAnimation(v, SpringAnimation.SCALE_Y);
//check if animation end listener is null
if (mEndListener == null) {
//create the animation end listener
mEndListener = new AnimationEndListener();
}
}
//save last click time to disable multi touch
mLastClickTime = SystemClock.elapsedRealtime();
if (animationX != null && animationY != null) {
//add the clicked view to soft reference
mEndListener.addToSoftReference(v);
//cancel pending animations
animationX.cancel();
animationY.cancel();
//decrease scale x and y of the view
v.setScaleX(0.925f);
v.setScaleY(0.925f);
//start animation x and y
animationX.start();
animationY.start();
//add end listener to check end of animation
animationY.addEndListener(mEndListener);
}
}
return true;// handle touch event
}
return false;//allow parent handle the touch event
}
/**
* Create and initialize Spring animation
*
* @param v view on which we need to add the spring effect
* @param property x property or y property
* @return spring animation object
*/
private SpringAnimation createAnimation(View v, DynamicAnimation.ViewProperty property) {
final SpringAnimation animation = new SpringAnimation(v, property);
SpringForce springForce = new SpringForce(INITIAL_SCALE);
springForce.setStiffness(SpringForce.STIFFNESS_MEDIUM);
springForce.setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY);
animation.setSpring(springForce);
return animation;
}
/**
* Sole purpose of this class is call the views on click listener if present.<br>
* The view is added to soft reference so that it can be garbage collected
* when the animation is finished we call the view's click listener which was added to soft reference
*/
private class AnimationEndListener implements DynamicAnimation.OnAnimationEndListener {
SoftReference<View> weakView;
private void addToSoftReference(View v) {
if (weakView == null) {
weakView = new SoftReference<>(v);
} else {
View view = weakView.get();
if (view == null) {
weakView = new SoftReference<>(v);
}
}
}
@Override
public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value, float velocity) {
View view = weakView.get();
if (view != null) {
//call onclick listener
view.callOnClick();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment