Created
November 11, 2014 21:58
-
-
Save JayNewstrom/bd75d9e304d1259a3640 to your computer and use it in GitHub Desktop.
A helper class to allow animation based touch states.
This file contains 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.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Paint; | |
import android.graphics.Path; | |
import android.graphics.RectF; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import android.view.ViewConfiguration; | |
import android.view.animation.Animation; | |
import android.view.animation.DecelerateInterpolator; | |
import android.view.animation.Transformation; | |
public final class TouchEffectAnimator { | |
private static final int EASE_ANIM_DURATION = 200; | |
private static final int MAX_RECT_ALPHA = 150; | |
private final View view; | |
private final int slop; | |
private int animInDuration = EASE_ANIM_DURATION; | |
private int animOutDuration = EASE_ANIM_DURATION; | |
private int rectAlpha = 0; | |
private Paint rectPaint = new Paint(); | |
private Path rectPath = new Path(); | |
private RectF viewRect; | |
private boolean touchReleased = true; | |
private boolean animatingFadeIn = false; | |
private Animation animationInProgress; | |
private boolean canceled; | |
private boolean hasPerformedFadeInAnimation; | |
private float downX; | |
private float downY; | |
public static TouchEffectAnimator setupListTouchEffectAnimator(View view) { | |
TouchEffectAnimator t = new TouchEffectAnimator(view); | |
t.setEffectColor(Color.LTGRAY); | |
t.setAnimInDuration(200); | |
t.setAnimOutDuration(500); | |
return t; | |
} | |
private final Animation.AnimationListener animationListener = new Animation.AnimationListener() { | |
@Override | |
public void onAnimationStart(Animation animation) { | |
animatingFadeIn = true; | |
} | |
@Override | |
public void onAnimationEnd(Animation animation) { | |
animationInProgress = null; | |
if (canceled) { | |
canceled = false; | |
} else { | |
animatingFadeIn = false; | |
if (touchReleased) { | |
fadeOutEffect(); | |
} | |
} | |
} | |
@Override | |
public void onAnimationRepeat(Animation animation) { | |
} | |
}; | |
public TouchEffectAnimator(View view) { | |
this.view = view; | |
ViewConfiguration vc = ViewConfiguration.get(view.getContext()); | |
this.slop = vc.getScaledTouchSlop(); | |
} | |
public void setAnimInDuration(int animInDuration) { | |
this.animInDuration = animInDuration; | |
} | |
public void setAnimOutDuration(int animOutDuration) { | |
this.animOutDuration = animOutDuration; | |
} | |
public void setEffectColor(int effectColor) { | |
rectPaint.setColor(effectColor); | |
rectPaint.setAlpha(rectAlpha); | |
} | |
public void onTouchEvent(final MotionEvent event) { | |
if (event.getActionMasked() == MotionEvent.ACTION_CANCEL) { | |
canceled = true; | |
touchReleased = true; | |
hasPerformedFadeInAnimation = false; | |
if (animationInProgress != null) { | |
animationInProgress.cancel(); | |
animationInProgress = null; | |
} | |
rectAlpha = 0; | |
view.invalidate(); | |
animatingFadeIn = false; | |
} | |
if (event.getActionMasked() == MotionEvent.ACTION_UP) { | |
touchReleased = true; | |
canceled = false; | |
if (!hasPerformedFadeInAnimation) { | |
fadeInEffect(); | |
} else if (!animatingFadeIn) { | |
fadeOutEffect(); | |
} | |
} else if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { | |
canceled = false; | |
if (touchReleased) { | |
touchReleased = false; | |
downX = event.getX(); | |
downY = event.getY(); | |
view.postDelayed(new Runnable() { | |
@Override public void run() { | |
if (!canceled && !hasPerformedFadeInAnimation) { | |
fadeInEffect(); | |
} | |
} | |
}, 100); | |
} | |
} else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { | |
if (!touchReleased && animationInProgress == null) { | |
if (Math.abs(downX - event.getX()) > slop || Math.abs(downY - event.getY()) > slop) { | |
canceled = true; | |
touchReleased = true; | |
} | |
} | |
} | |
} | |
public void onDraw(final Canvas canvas) { | |
if (rectPaint.getAlpha() != rectAlpha) { | |
rectPath.reset(); | |
rectPaint.setAlpha(rectAlpha); | |
} | |
canvas.drawRoundRect(getViewRect(), 0, 0, rectPaint); | |
} | |
private RectF getViewRect() { | |
if (viewRect == null || viewRect.width() == 0 || viewRect.height() == 0) { | |
viewRect = new RectF(0, 0, view.getWidth(), view.getHeight()); | |
} | |
return viewRect; | |
} | |
private void fadeInEffect() { | |
hasPerformedFadeInAnimation = true; | |
rectAlpha = 0; | |
animationInProgress = new Animation() { | |
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { | |
rectAlpha = (int) (MAX_RECT_ALPHA * interpolatedTime); | |
view.invalidate(); | |
} | |
}; | |
animationInProgress.setInterpolator(new DecelerateInterpolator()); | |
animationInProgress.setDuration(animInDuration); | |
animationInProgress.setAnimationListener(animationListener); | |
view.startAnimation(animationInProgress); | |
} | |
private void fadeOutEffect() { | |
hasPerformedFadeInAnimation = false; | |
animationInProgress = new Animation() { | |
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { | |
rectAlpha = MAX_RECT_ALPHA - (int) (MAX_RECT_ALPHA * interpolatedTime); | |
view.invalidate(); | |
} | |
}; | |
animationInProgress.setDuration(animOutDuration); | |
view.startAnimation(animationInProgress); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment