Created
October 5, 2017 11:58
-
-
Save SachinR90/00536fda826e9286faaf30126085853b to your computer and use it in GitHub Desktop.
CustomOnTouchListener
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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