Created
March 15, 2016 10:37
-
-
Save anonymous/192935d71857a6d7b3db to your computer and use it in GitHub Desktop.
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
public class DraweeTransform extends Transition { | |
private static final String PROPNAME_MATRIX = "draweeTransform:matrix"; | |
private final boolean enter; | |
private final ScalingUtils.ScaleType detailScale; | |
public DraweeTransform(ScalingUtils.ScaleType detailScale, boolean enter) { | |
this.detailScale = detailScale; | |
this.enter = enter; | |
} | |
@Override | |
public void captureStartValues(TransitionValues transitionValues) { | |
ScaleTypeDrawable drawable = getActualImageDrawable(transitionValues); | |
if (drawable != null) { | |
Matrix transform = new Matrix(); | |
if (enter) { | |
ScalingUtils.ScaleType scaleType = drawable.getScaleType(); | |
drawable.setScaleType(detailScale); | |
drawable.getTransform(transform); | |
drawable.setScaleType(scaleType); | |
} else { | |
drawable.getTransform(transform); | |
} | |
transitionValues.values.put(PROPNAME_MATRIX, transform); | |
} | |
} | |
@Override | |
public void captureEndValues(TransitionValues transitionValues) { | |
ScaleTypeDrawable drawable = getActualImageDrawable(transitionValues); | |
if (drawable != null) { | |
Matrix transform = new Matrix(); | |
if (!enter) { | |
ScalingUtils.ScaleType scaleType = drawable.getScaleType(); | |
drawable.setScaleType(detailScale); | |
drawable.getTransform(transform); | |
drawable.setScaleType(scaleType); | |
} else { | |
drawable.getTransform(transform); | |
} | |
transitionValues.values.put(PROPNAME_MATRIX, transform); | |
} | |
} | |
private ScaleTypeDrawable getActualImageDrawable(TransitionValues transitionValues) { | |
if (transitionValues.view != null && transitionValues.view instanceof GenericDraweeView) { | |
GenericDraweeView genericDraweeView = (GenericDraweeView) transitionValues.view; | |
int actualImageIndex; | |
try { | |
Field field = GenericDraweeHierarchy.class.getDeclaredField("mActualImageIndex"); | |
field.setAccessible(true); | |
actualImageIndex = (int) field.get(genericDraweeView.getHierarchy()); | |
} catch (Exception e) { | |
return null; | |
} | |
Drawable topLevelDrawable = genericDraweeView.getTopLevelDrawable(); | |
if (topLevelDrawable instanceof ForwardingDrawable) { | |
ForwardingDrawable root = (ForwardingDrawable) topLevelDrawable; | |
if (root.getCurrent() instanceof FadeDrawable) { | |
FadeDrawable current = (FadeDrawable) root.getCurrent(); | |
for (int i = 0; i < current.getNumberOfLayers(); i++) { | |
Drawable layer = current.getDrawable(i); | |
if (layer instanceof ScaleTypeDrawable && i == actualImageIndex) { | |
return (ScaleTypeDrawable) layer; | |
} | |
} | |
} | |
} | |
} | |
return null; | |
} | |
@Override | |
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) { | |
if (startValues == null || endValues == null || !(startValues.view instanceof GenericDraweeView)) { | |
return null; | |
} | |
ScaleTypeDrawable actualImageDrawable = getActualImageDrawable(endValues); | |
if (actualImageDrawable == null) { | |
return null; | |
} | |
GenericDraweeView genericDraweeView = (GenericDraweeView) endValues.view; | |
Matrix startMatrix = (Matrix) startValues.values.get(PROPNAME_MATRIX); | |
Matrix endMatrix = (Matrix) endValues.values.get(PROPNAME_MATRIX); | |
if (startMatrix == null || endMatrix == null) { | |
return null; | |
} | |
actualImageDrawable.setAlpha(0); | |
MatrixDrawable matrixDrawable = new MatrixDrawable(actualImageDrawable.getDrawable(), startMatrix); | |
genericDraweeView.getHierarchy().setControllerOverlay(matrixDrawable); | |
MatrixEvaluator evaluator = new MatrixEvaluator(); | |
ValueAnimator animator = ValueAnimator.ofFloat(0, 1); | |
animator.addUpdateListener(animation -> { | |
float fraction = (float) animation.getAnimatedValue(); | |
Matrix matrix = evaluator.evaluate(fraction, startMatrix, endMatrix); | |
matrixDrawable.setMatrix(matrix); | |
}); | |
animator.addListener(new Animator.AnimatorListener() { | |
@Override | |
public void onAnimationStart(Animator animation) { | |
actualImageDrawable.setAlpha(0); | |
} | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
animation.removeListener(this); | |
actualImageDrawable.setAlpha(255); | |
} | |
@Override | |
public void onAnimationCancel(Animator animation) { | |
animation.removeListener(this); | |
actualImageDrawable.setAlpha(255); | |
} | |
@Override | |
public void onAnimationRepeat(Animator animation) {} | |
}); | |
return animator; | |
} | |
private static class MatrixEvaluator implements TypeEvaluator<Matrix> { | |
float[] mTempStartValues = new float[9]; | |
float[] mTempEndValues = new float[9]; | |
Matrix mTempMatrix = new Matrix(); | |
@Override | |
public Matrix evaluate(float fraction, Matrix startValue, Matrix endValue) { | |
startValue.getValues(mTempStartValues); | |
endValue.getValues(mTempEndValues); | |
for (int i = 0; i < 9; i++) { | |
float diff = mTempEndValues[i] - mTempStartValues[i]; | |
mTempEndValues[i] = mTempStartValues[i] + (fraction * diff); | |
} | |
mTempMatrix.setValues(mTempEndValues); | |
return mTempMatrix; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment