Last active
August 29, 2015 14:17
-
-
Save Takhion/bf3bb4495f6388b659ce 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
import android.animation.Animator; | |
import android.animation.AnimatorSet; | |
import android.animation.Keyframe; | |
import android.animation.PropertyValuesHolder; | |
import android.animation.ValueAnimator; | |
import android.os.Build; | |
import android.support.annotation.Nullable; | |
import java.lang.reflect.Field; | |
public final class AnimatorUtils | |
{ | |
private static final boolean SUPPORTED; | |
private static final Class<?> CLASS__INT_KEYFRAME_SET; | |
private static final Class<?> CLASS__FLOAT_KEYFRAME_SET; | |
private static final Field FIELD__PROPERTY_VALUES_HOLDER__KEYFRAME_SET; | |
private static final Field FIELD__KEYFRAME_SET__FIRST_KEYFRAME; | |
private static final Field FIELD__KEYFRAME__HAS_VALUE; | |
private static final Field FIELD__INT_KEYFRAME_SET__FIRST_TIME; | |
private static final Field FIELD__FLOAT_KEYFRAME_SET__FIRST_TIME; | |
static | |
{ | |
boolean supported = false; | |
Class<?> class_IntKeyframeSet = null; | |
Class<?> class_FloatKeyframeSet = null; | |
Field field_PropertyValuesHolder_mKeyframeSet = null; | |
Field field_KeyframeSet_mFirstKeyframe = null; | |
Field field_Keyframe_hasValue = null; | |
Field field_IntKeyframeSet_firstTime = null; | |
Field field_FloatKeyframeSet_firstTime = null; | |
if (Build.VERSION.SDK_INT < 21) | |
{ | |
//noinspection TryWithIdenticalCatches | |
try | |
{ | |
final Class class_KeyframeSet = Class.forName("android.animation.KeyframeSet"); | |
class_IntKeyframeSet = Class.forName("android.animation.IntKeyframeSet"); | |
class_FloatKeyframeSet = Class.forName("android.animation.FloatKeyframeSet"); | |
field_PropertyValuesHolder_mKeyframeSet = PropertyValuesHolder.class.getDeclaredField("mKeyframeSet"); | |
field_PropertyValuesHolder_mKeyframeSet.setAccessible(true); | |
field_KeyframeSet_mFirstKeyframe = class_KeyframeSet.getDeclaredField("mFirstKeyframe"); | |
field_KeyframeSet_mFirstKeyframe.setAccessible(true); | |
field_Keyframe_hasValue = Keyframe.class.getDeclaredField("mHasValue"); | |
field_Keyframe_hasValue.setAccessible(true); | |
field_IntKeyframeSet_firstTime = class_IntKeyframeSet.getDeclaredField("firstTime"); | |
field_IntKeyframeSet_firstTime.setAccessible(true); | |
field_FloatKeyframeSet_firstTime = class_FloatKeyframeSet.getDeclaredField("firstTime"); | |
field_FloatKeyframeSet_firstTime.setAccessible(true); | |
supported = true; | |
} | |
catch (NoSuchFieldException ignore) | |
{ | |
} | |
catch (ClassNotFoundException ignore) | |
{ | |
} | |
} | |
SUPPORTED = supported; | |
CLASS__INT_KEYFRAME_SET = class_IntKeyframeSet; | |
CLASS__FLOAT_KEYFRAME_SET = class_FloatKeyframeSet; | |
FIELD__PROPERTY_VALUES_HOLDER__KEYFRAME_SET = field_PropertyValuesHolder_mKeyframeSet; | |
FIELD__KEYFRAME_SET__FIRST_KEYFRAME = field_KeyframeSet_mFirstKeyframe; | |
FIELD__KEYFRAME__HAS_VALUE = field_Keyframe_hasValue; | |
FIELD__INT_KEYFRAME_SET__FIRST_TIME = field_IntKeyframeSet_firstTime; | |
FIELD__FLOAT_KEYFRAME_SET__FIRST_TIME = field_FloatKeyframeSet_firstTime; | |
} | |
private AnimatorUtils() {} | |
public static void resetStartValues(@Nullable Animator animator) | |
{ | |
// see https://github.com/android/platform_frameworks_base/commit/8619f48fb353740f7fd3f6eaa86fe493377e6cad | |
if (!SUPPORTED || animator == null) { return; } | |
if (animator instanceof AnimatorSet) | |
{ | |
for (Animator childAnimator : ((AnimatorSet)animator).getChildAnimations()) | |
{ | |
resetStartValues(childAnimator); | |
} | |
} | |
else if (animator instanceof ValueAnimator) | |
{ | |
final PropertyValuesHolder[] values = ((ValueAnimator)animator).getValues(); | |
if (values != null) | |
{ | |
try | |
{ | |
for (PropertyValuesHolder pvh : values) | |
{ | |
final Object mKeyframeSet = FIELD__PROPERTY_VALUES_HOLDER__KEYFRAME_SET.get(pvh); | |
if (mKeyframeSet != null) | |
{ | |
final Object mFirstKeyframe = FIELD__KEYFRAME_SET__FIRST_KEYFRAME.get(mKeyframeSet); | |
if (mFirstKeyframe != null) | |
{ | |
FIELD__KEYFRAME__HAS_VALUE.set(mFirstKeyframe, false); | |
} | |
final Class<?> keyframeSetClass = mKeyframeSet.getClass(); | |
if (CLASS__INT_KEYFRAME_SET.isAssignableFrom(keyframeSetClass)) | |
{ | |
FIELD__INT_KEYFRAME_SET__FIRST_TIME.set(mKeyframeSet, true); | |
} | |
else if (CLASS__FLOAT_KEYFRAME_SET.isAssignableFrom(keyframeSetClass)) | |
{ | |
FIELD__FLOAT_KEYFRAME_SET__FIRST_TIME.set(mKeyframeSet, true); | |
} | |
} | |
} | |
} | |
catch (IllegalAccessException ignore) | |
{ | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment