package com.luciofm.droidcon.ifican.anim;
import android.animation.Animator;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.transition.Transition;
import android.transition.TransitionValues;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.TextView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* Created by luciofm on 10/17/14.
*/
public class TextTransform extends Transition {
private static final String PROPNAME_TEXTSIZE = "android:textTransform:textSize";
private static final String PROPNAME_TEXTCOLOR = "android:textTransform:textColor";
private static final String PROPNAME_PARENT = "android:textTransform:parent";
private static final String PROPNAME_WINDOW_X = "android:textTransform:windowX";
private static final String PROPNAME_WINDOW_Y = "android:textTransform:windowY";
int[] tempLocation = new int[2];
private Method suppressLayout;
private void captureValues(TransitionValues values) {
View view = values.view;
if (!(view instanceof TextView))
return;
TextView text = (TextView) view;
values.values.put(PROPNAME_TEXTSIZE, pixelsToSp(view.getContext(), text.getTextSize()));
values.values.put(PROPNAME_TEXTCOLOR, ((TextView) view).getTextColors().getDefaultColor());
values.values.put(PROPNAME_PARENT, view.getParent());
values.view.getLocationInWindow(tempLocation);
values.values.put(PROPNAME_WINDOW_X, tempLocation[0]);
values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]);
}
@Override
public void captureStartValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
@Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
}
Map<String, Object> startParentVals = startValues.values;
Map<String, Object> endParentVals = endValues.values;
ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
if (startParent == null || endParent == null) {
return null;
}
final View view = endValues.view;
boolean parentsEqual = (startParent == endParent) ||
(startParent.getId() == endParent.getId());
if (!parentsEqual || !(view instanceof TextView))
return null;
int numChanges = 0;
float startSize = (float) startValues.values.get(PROPNAME_TEXTSIZE);
float endSize = (float) endValues.values.get(PROPNAME_TEXTSIZE);
int startX = (int) startValues.values.get(PROPNAME_WINDOW_X);
int endX = (int) endValues.values.get(PROPNAME_WINDOW_X);
int startY = (int) startValues.values.get(PROPNAME_WINDOW_Y);
int endY = (int) endValues.values.get(PROPNAME_WINDOW_Y);
int startColor = (int) startValues.values.get(PROPNAME_TEXTCOLOR);
int endColor = (int) endValues.values.get(PROPNAME_TEXTCOLOR);
if (startSize != endSize) numChanges++;
if (startX != endX) numChanges++;
if (startY != endY) numChanges++;
if (startColor != endColor) numChanges++;
if (numChanges > 0) {
PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
int pvhIndex = 0;
if (startX != endX) {
float delta = startX - endX;
view.setTranslationX(delta);
pvh[pvhIndex++] = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 0);
}
if (startY != endY) {
float delta = startY - endY;
view.setTranslationY(delta);
pvh[pvhIndex++] = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0);
}
if (startSize != endSize) {
((TextView) view).setTextSize(startSize);
pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("textSize", startSize - 1, endSize);
}
if (startColor != endColor) {
((TextView) view).setTextColor(startColor);
pvh[pvhIndex++] = PropertyValuesHolder.ofObject("textColor",
new ArgbEvaluator(), startColor, endColor);
}
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
/*anim.addListener(new LayerEnablingAnimatorListener(view));
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
int frame = 0;
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Log.d("Droidcon", "Frame: " + frame);
frame++;
}
});*/
return anim;
}
return null;
}
float pixelsToSp(Context context, float px) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px/scaledDensity;
}
void callSuppressLayout(ViewGroup viewGroup, boolean value) {
if (suppressLayout != null) {
try {
suppressLayout.invoke(viewGroup, value);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return;
}
try {
suppressLayout = viewGroup.getClass().getMethod("suppressLayout", Boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}