/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.transition; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.util.Log; import android.view.SurfaceView; import android.view.TextureView; import android.view.View; import android.view.ViewGroup; import android.view.ViewOverlay; import java.util.Map; /** * This transition captures bitmap representations of target views before and * after the scene change and fades between them. * *
Note: This transition is not compatible with {@link TextureView} * or {@link SurfaceView}.
* * @hide */ public class Crossfade extends Transition { // TODO: Add a hook that lets a Transition call user code to query whether it should run on // a given target view. This would save bitmap comparisons in this transition, for example. private static final String LOG_TAG = "Crossfade"; private static final String PROPNAME_BITMAP = "android:crossfade:bitmap"; private static final String PROPNAME_DRAWABLE = "android:crossfade:drawable"; private static final String PROPNAME_BOUNDS = "android:crossfade:bounds"; private static RectEvaluator sRectEvaluator = new RectEvaluator(); private int mFadeBehavior = FADE_BEHAVIOR_REVEAL; private int mResizeBehavior = RESIZE_BEHAVIOR_SCALE; /** * Flag specifying that the fading animation should cross-fade * between the old and new representation of all affected target * views. This means that the old representation will fade out * while the new one fades in. This effect may work well on views * without solid backgrounds, such as TextViews. * * @see #setFadeBehavior(int) */ public static final int FADE_BEHAVIOR_CROSSFADE = 0; /** * Flag specifying that the fading animation should reveal the * new representation of all affected target views. This means * that the old representation will fade out, gradually * revealing the new representation, which remains opaque * the whole time. This effect may work well on views * with solid backgrounds, such as ImageViews. * * @see #setFadeBehavior(int) */ public static final int FADE_BEHAVIOR_REVEAL = 1; /** * Flag specifying that the fading animation should first fade * out the original representation completely and then fade in the * new one. This effect may be more suitable than the other * fade behaviors for views with. * * @see #setFadeBehavior(int) */ public static final int FADE_BEHAVIOR_OUT_IN = 2; /** * Flag specifying that the transition should not animate any * changes in size between the old and new target views. * This means that no scaling will take place as a result of * this transition * * @see #setResizeBehavior(int) */ public static final int RESIZE_BEHAVIOR_NONE = 0; /** * Flag specifying that the transition should animate any * changes in size between the old and new target views. * This means that the animation will scale the start/end * representations of affected views from the starting size * to the ending size over the course of the animation. * This effect may work well on images, but is not recommended * for text. * * @see #setResizeBehavior(int) */ public static final int RESIZE_BEHAVIOR_SCALE = 1; // TODO: Add fade/resize behaviors to xml resources /** * Sets the type of fading animation that will be run, one of * {@link #FADE_BEHAVIOR_CROSSFADE} and {@link #FADE_BEHAVIOR_REVEAL}. * * @param fadeBehavior The type of fading animation to use when this * transition is run. */ public Crossfade setFadeBehavior(int fadeBehavior) { if (fadeBehavior >= FADE_BEHAVIOR_CROSSFADE && fadeBehavior <= FADE_BEHAVIOR_OUT_IN) { mFadeBehavior = fadeBehavior; } return this; } /** * Returns the fading behavior of the animation. * * @return This crossfade object. * @see #setFadeBehavior(int) */ public int getFadeBehavior() { return mFadeBehavior; } /** * Sets the type of resizing behavior that will be used during the * transition animation, one of {@link #RESIZE_BEHAVIOR_NONE} and * {@link #RESIZE_BEHAVIOR_SCALE}. * * @param resizeBehavior The type of resizing behavior to use when this * transition is run. */ public Crossfade setResizeBehavior(int resizeBehavior) { if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) { mResizeBehavior = resizeBehavior; } return this; } /** * Returns the resizing behavior of the animation. * * @return This crossfade object. * @see #setResizeBehavior(int) */ public int getResizeBehavior() { return mResizeBehavior; } @Override public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) { if (startValues == null || endValues == null) { return null; } final boolean useParentOverlay = mFadeBehavior != FADE_BEHAVIOR_REVEAL; final View view = endValues.view; Map