SetupAnimationHelper.java revision 1abddd9f6225298066094e20a6c29061b6af4590
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.tv.common.ui.setup.animation; 18 19import android.animation.Animator; 20import android.animation.AnimatorListenerAdapter; 21import android.animation.AnimatorSet; 22import android.animation.ObjectAnimator; 23import android.animation.TypeEvaluator; 24import android.transition.Transition; 25import android.transition.TransitionSet; 26import android.view.Gravity; 27import android.view.View; 28import android.widget.ImageView; 29 30/** 31 * A helper class for setup animation. 32 */ 33public final class SetupAnimationHelper { 34 public static final long DELAY_BETWEEN_SIBLINGS_MS = applyAnimationTimeScale(33); 35 36 private static final float ANIMATION_SCALE = 1.0f; 37 38 private static long sFragmentTransitionDuration; 39 private static int sFragmentTransitionDistance; 40 41 private SetupAnimationHelper() { } 42 43 /** 44 * Sets the duration of the fragment transition. 45 */ 46 public static void setFragmentTransitionDuration(long duration) { 47 sFragmentTransitionDuration = duration; 48 } 49 50 /** 51 * Sets the distance of the fragment transition. 52 */ 53 public static void setFragmentTransitionDistance(int distance) { 54 sFragmentTransitionDistance = distance; 55 } 56 57 public static class TransitionBuilder { 58 private int mSlideEdge = Gravity.START; 59 private int mDistance = sFragmentTransitionDistance; 60 private long mDuration = sFragmentTransitionDuration; 61 private int[] mParentIdForDelay; 62 private int[] mExcludeIds; 63 64 /** 65 * Sets the edge of the slide transition. 66 * 67 * @see android.transition.Slide#setSlideEdge 68 */ 69 public TransitionBuilder setSlideEdge(int slideEdge) { 70 mSlideEdge = slideEdge; 71 return this; 72 } 73 74 /** 75 * Sets the duration of the transition. 76 */ 77 public TransitionBuilder setDuration(long duration) { 78 mDuration = duration; 79 return this; 80 } 81 82 /** 83 * Sets the ID of the view whose descendants will perform delayed move. 84 * 85 * @see android.view.ViewGroup#isTransitionGroup 86 */ 87 public TransitionBuilder setParentIdsForDelay(int[] parentIdForDelay) { 88 mParentIdForDelay = parentIdForDelay; 89 return this; 90 } 91 92 /** 93 * Sets the ID's of the views which will not be included in the transition. 94 */ 95 public TransitionBuilder setExcludeIds(int[] excludeIds) { 96 mExcludeIds = excludeIds; 97 return this; 98 } 99 100 /** 101 * Builds and returns the {@link android.transition.Transition}. 102 */ 103 public Transition build() { 104 FadeAndShortSlide transition = new FadeAndShortSlide(mSlideEdge, mParentIdForDelay); 105 transition.setDistance(mDistance); 106 transition.setDuration(mDuration); 107 if (mExcludeIds != null) { 108 for (int id : mExcludeIds) { 109 transition.excludeTarget(id, true); 110 } 111 } 112 return transition; 113 } 114 } 115 116 /** 117 * Applies the animation scale to the given {@code animator}. 118 */ 119 public static Animator applyAnimationTimeScale(Animator animator) { 120 if (animator instanceof AnimatorSet) { 121 for (Animator child : ((AnimatorSet) animator).getChildAnimations()) { 122 applyAnimationTimeScale(child); 123 } 124 } 125 if (animator.getDuration() > 0) { 126 animator.setDuration((long) (animator.getDuration() * ANIMATION_SCALE)); 127 } 128 animator.setStartDelay((long) (animator.getStartDelay() * ANIMATION_SCALE)); 129 return animator; 130 } 131 132 /** 133 * Applies the animation scale to the given {@code transition}. 134 */ 135 public static Transition applyAnimationTimeScale(Transition transition) { 136 if (transition instanceof TransitionSet) { 137 TransitionSet set = (TransitionSet) transition; 138 int count = set.getTransitionCount(); 139 for (int i = 0; i < count; ++i) { 140 applyAnimationTimeScale(set.getTransitionAt(i)); 141 } 142 } 143 if (transition.getDuration() > 0) { 144 transition.setDuration((long) (transition.getDuration() * ANIMATION_SCALE)); 145 } 146 transition.setStartDelay((long) (transition.getStartDelay() * ANIMATION_SCALE)); 147 return transition; 148 } 149 150 /** 151 * Applies the animation scale to the given {@code time}. 152 */ 153 public static long applyAnimationTimeScale(long time) { 154 return (long) (time * ANIMATION_SCALE); 155 } 156 157 /** 158 * Returns an animator which animate the source image of the {@link ImageView}. 159 * 160 * <p>The frame rate is 60 fps. 161 */ 162 public static ObjectAnimator createFrameAnimator(ImageView imageView, int[] frames) { 163 return createFrameAnimatorWithDelay(imageView, frames, 0); 164 } 165 166 /** 167 * Returns an animator which animate the source image of the {@link ImageView} with start delay. 168 * 169 * <p>The frame rate is 60 fps. 170 */ 171 public static ObjectAnimator createFrameAnimatorWithDelay(ImageView imageView, int[] frames, 172 long startDelay) { 173 ObjectAnimator animator = ObjectAnimator.ofInt(imageView, "imageResource", frames); 174 // Make it 60 fps. 175 animator.setDuration(frames.length * 1000 / 60); 176 animator.setInterpolator(null); 177 animator.setStartDelay(startDelay); 178 animator.setEvaluator(new TypeEvaluator<Integer>() { 179 @Override 180 public Integer evaluate(float fraction, Integer startValue, Integer endValue) { 181 return startValue; 182 } 183 }); 184 return animator; 185 } 186 187 /** 188 * Creates a fade out animator. 189 * 190 * @param view The view which will be animated. 191 * @param duration The duration of the animation. 192 * @param makeVisibleAfterAnimation If {@code true}, the view will become visible after the 193 * animation ends. 194 */ 195 public static Animator createFadeOutAnimator(final View view, int duration, 196 boolean makeVisibleAfterAnimation) { 197 ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, 1.0f, 0.0f); 198 if (makeVisibleAfterAnimation) { 199 animator.addListener(new AnimatorListenerAdapter() { 200 @Override 201 public void onAnimationEnd(Animator animation) { 202 view.setAlpha(1.0f); 203 } 204 }); 205 } 206 return animator; 207 } 208} 209