Skip to content

Instantly share code, notes, and snippets.

Created March 15, 2016 10:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/192935d71857a6d7b3db to your computer and use it in GitHub Desktop.
Save anonymous/192935d71857a6d7b3db to your computer and use it in GitHub Desktop.
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