11abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/* 21abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Copyright (C) 2015 The Android Open Source Project 31abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 41abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 51abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * you may not use this file except in compliance with the License. 61abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * You may obtain a copy of the License at 71abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 81abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 91abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Unless required by applicable law or agreed to in writing, software 111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * See the License for the specific language governing permissions and 141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * limitations under the License. 151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 171abddd9f6225298066094e20a6c29061b6af4590Nick Chalkopackage com.android.tv.common.ui.setup.animation; 181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 191abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.animation.Animator; 201abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.animation.AnimatorListenerAdapter; 211abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.animation.AnimatorSet; 221abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.animation.ObjectAnimator; 231abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.animation.TypeEvaluator; 24ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.content.Context; 251abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.transition.Transition; 261abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.transition.TransitionSet; 271abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.view.Gravity; 281abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.view.View; 291abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoimport android.widget.ImageView; 301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 31ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport com.android.tv.common.R; 32ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/** 341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * A helper class for setup animation. 351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 361abddd9f6225298066094e20a6c29061b6af4590Nick Chalkopublic final class SetupAnimationHelper { 371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static final long DELAY_BETWEEN_SIBLINGS_MS = applyAnimationTimeScale(33); 381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 39ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private static final float ANIMATION_TIME_SCALE = 1.0f; 401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 41ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private static boolean sInitialized; 421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private static long sFragmentTransitionDuration; 43ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private static int sFragmentTransitionLongDistance; 44ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private static int sFragmentTransitionShortDistance; 451abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 461abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private SetupAnimationHelper() { } 471abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 49ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Load initial parameters. This method should be called before using this class. 501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 51ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static void initialize(Context context) { 5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (sInitialized) { 5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 5465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 55ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko sFragmentTransitionDuration = context.getResources() 56ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko .getInteger(R.integer.setup_fragment_transition_duration); 57ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko sFragmentTransitionLongDistance = context.getResources() 58ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko .getDimensionPixelOffset(R.dimen.setup_fragment_transition_long_distance); 59ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko sFragmentTransitionShortDistance = context.getResources() 60ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko .getDimensionPixelOffset(R.dimen.setup_fragment_transition_short_distance); 61ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko sInitialized = true; 621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 64ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private static void checkInitialized() { 65ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (!sInitialized) { 66ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko throw new IllegalStateException("SetupAnimationHelper not initialized"); 67ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 681abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 691abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 701abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static class TransitionBuilder { 711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private int mSlideEdge = Gravity.START; 7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private final int mDistance = sFragmentTransitionLongDistance; 731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private long mDuration = sFragmentTransitionDuration; 741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private int[] mParentIdForDelay; 751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko private int[] mExcludeIds; 761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 77ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public TransitionBuilder() { 78ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko checkInitialized(); 79ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 80ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 811abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 821abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Sets the edge of the slide transition. 831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * @see android.transition.Slide#setSlideEdge 851abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public TransitionBuilder setSlideEdge(int slideEdge) { 871abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mSlideEdge = slideEdge; 881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return this; 891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 901abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 911abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 921abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Sets the duration of the transition. 931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public TransitionBuilder setDuration(long duration) { 951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mDuration = duration; 961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return this; 971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 1001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Sets the ID of the view whose descendants will perform delayed move. 1011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 1021abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * @see android.view.ViewGroup#isTransitionGroup 1031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public TransitionBuilder setParentIdsForDelay(int[] parentIdForDelay) { 1051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mParentIdForDelay = parentIdForDelay; 1061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return this; 1071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 1101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Sets the ID's of the views which will not be included in the transition. 1111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public TransitionBuilder setExcludeIds(int[] excludeIds) { 1131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mExcludeIds = excludeIds; 1141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return this; 1151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1171abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 1181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Builds and returns the {@link android.transition.Transition}. 1191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public Transition build() { 1211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko FadeAndShortSlide transition = new FadeAndShortSlide(mSlideEdge, mParentIdForDelay); 1221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko transition.setDistance(mDistance); 1231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko transition.setDuration(mDuration); 1241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mExcludeIds != null) { 1251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko for (int id : mExcludeIds) { 1261abddd9f6225298066094e20a6c29061b6af4590Nick Chalko transition.excludeTarget(id, true); 1271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1281abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return transition; 1301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 134ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Changes the move distance of the {@code transition} to long distance. 135ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 136ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static void setLongDistance(FadeAndShortSlide transition) { 137ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko checkInitialized(); 138ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko transition.setDistance(sFragmentTransitionLongDistance); 139ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 140ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 141ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 142ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Changes the move distance of the {@code transition} to short distance. 143ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 144ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static void setShortDistance(FadeAndShortSlide transition) { 145ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko checkInitialized(); 146ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko transition.setDistance(sFragmentTransitionShortDistance); 147ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 148ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 149ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 1501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Applies the animation scale to the given {@code animator}. 1511abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1521abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static Animator applyAnimationTimeScale(Animator animator) { 1531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (animator instanceof AnimatorSet) { 1541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko for (Animator child : ((AnimatorSet) animator).getChildAnimations()) { 1551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko applyAnimationTimeScale(child); 1561abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1581abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (animator.getDuration() > 0) { 159ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko animator.setDuration((long) (animator.getDuration() * ANIMATION_TIME_SCALE)); 1601abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 161ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko animator.setStartDelay((long) (animator.getStartDelay() * ANIMATION_TIME_SCALE)); 1621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return animator; 1631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 1661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Applies the animation scale to the given {@code transition}. 1671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1681abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static Transition applyAnimationTimeScale(Transition transition) { 1691abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (transition instanceof TransitionSet) { 1701abddd9f6225298066094e20a6c29061b6af4590Nick Chalko TransitionSet set = (TransitionSet) transition; 1711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int count = set.getTransitionCount(); 1721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko for (int i = 0; i < count; ++i) { 1731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko applyAnimationTimeScale(set.getTransitionAt(i)); 1741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (transition.getDuration() > 0) { 177ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko transition.setDuration((long) (transition.getDuration() * ANIMATION_TIME_SCALE)); 1781abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 179ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko transition.setStartDelay((long) (transition.getStartDelay() * ANIMATION_TIME_SCALE)); 1801abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return transition; 1811abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1821abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 1841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Applies the animation scale to the given {@code time}. 1851abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static long applyAnimationTimeScale(long time) { 187ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return (long) (time * ANIMATION_TIME_SCALE); 1881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1901abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 191ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Returns an animator which animates the source image of the {@link ImageView}. 1921abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 1931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * <p>The frame rate is 60 fps. 1941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 1951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static ObjectAnimator createFrameAnimator(ImageView imageView, int[] frames) { 1961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return createFrameAnimatorWithDelay(imageView, frames, 0); 1971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 200ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Returns an animator which animates the source image of the {@link ImageView} with start delay. 2011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 2021abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * <p>The frame rate is 60 fps. 2031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 2041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public static ObjectAnimator createFrameAnimatorWithDelay(ImageView imageView, int[] frames, 2051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko long startDelay) { 2061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ObjectAnimator animator = ObjectAnimator.ofInt(imageView, "imageResource", frames); 2071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko // Make it 60 fps. 2081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko animator.setDuration(frames.length * 1000 / 60); 2091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko animator.setInterpolator(null); 2101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko animator.setStartDelay(startDelay); 2111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko animator.setEvaluator(new TypeEvaluator<Integer>() { 2121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko @Override 2131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public Integer evaluate(float fraction, Integer startValue, Integer endValue) { 2141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return startValue; 2151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko }); 2171abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return animator; 2181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /** 2211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Creates a fade out animator. 2221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 2231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * @param view The view which will be animated. 2241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * @param duration The duration of the animation. 2251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * @param makeVisibleAfterAnimation If {@code true}, the view will become visible after the 2261abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * animation ends. 2271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 228ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static Animator createFadeOutAnimator(final View view, long duration, 2291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko boolean makeVisibleAfterAnimation) { 230ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko ObjectAnimator animator = 231ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f).setDuration(duration); 2321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (makeVisibleAfterAnimation) { 2331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko animator.addListener(new AnimatorListenerAdapter() { 2341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko @Override 2351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko public void onAnimationEnd(Animator animation) { 2361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko view.setAlpha(1.0f); 2371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko }); 2391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return animator; 2411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 243