FileDocCategorySizeDatePackage
Crossfade.javaAPI DocAndroid 5.1 API12243Thu Mar 12 22:22:10 GMT 2015android.transition

Crossfade

public class Crossfade extends Transition
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

Fields Summary
private static final String
LOG_TAG
private static final String
PROPNAME_BITMAP
private static final String
PROPNAME_DRAWABLE
private static final String
PROPNAME_BOUNDS
private static android.animation.RectEvaluator
sRectEvaluator
private int
mFadeBehavior
private int
mResizeBehavior
public static final int
FADE_BEHAVIOR_CROSSFADE
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.
public static final int
FADE_BEHAVIOR_REVEAL
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.
public static final int
FADE_BEHAVIOR_OUT_IN
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.
public static final int
RESIZE_BEHAVIOR_NONE
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
public static final int
RESIZE_BEHAVIOR_SCALE
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.
Constructors Summary
Methods Summary
public voidcaptureEndValues(TransitionValues transitionValues)

        captureValues(transitionValues);
    
public voidcaptureStartValues(TransitionValues transitionValues)

        captureValues(transitionValues);
    
private voidcaptureValues(TransitionValues transitionValues)

        View view = transitionValues.view;
        Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
        if (mFadeBehavior != FADE_BEHAVIOR_REVEAL) {
            bounds.offset(view.getLeft(), view.getTop());
        }
        transitionValues.values.put(PROPNAME_BOUNDS, bounds);

        if (Transition.DBG) {
            Log.d(LOG_TAG, "Captured bounds " + transitionValues.values.get(PROPNAME_BOUNDS));
        }
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
                Bitmap.Config.ARGB_8888);
        if (view instanceof TextureView) {
            bitmap = ((TextureView) view).getBitmap();
        } else {
            Canvas c = new Canvas(bitmap);
            view.draw(c);
        }
        transitionValues.values.put(PROPNAME_BITMAP, bitmap);
        // TODO: I don't have resources, can't call the non-deprecated method?
        BitmapDrawable drawable = new BitmapDrawable(bitmap);
        // TODO: lrtb will be wrong if the view has transXY set
        drawable.setBounds(bounds);
        transitionValues.values.put(PROPNAME_DRAWABLE, drawable);
    
public android.animation.AnimatorcreateAnimator(android.view.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<String, Object> startVals = startValues.values;
        Map<String, Object> endVals = endValues.values;
        Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS);
        Rect endBounds = (Rect) endVals.get(PROPNAME_BOUNDS);
        Bitmap startBitmap = (Bitmap) startVals.get(PROPNAME_BITMAP);
        Bitmap endBitmap = (Bitmap) endVals.get(PROPNAME_BITMAP);
        final BitmapDrawable startDrawable = (BitmapDrawable) startVals.get(PROPNAME_DRAWABLE);
        final BitmapDrawable endDrawable = (BitmapDrawable) endVals.get(PROPNAME_DRAWABLE);
        if (Transition.DBG) {
            Log.d(LOG_TAG, "StartBitmap.sameAs(endBitmap) = " + startBitmap.sameAs(endBitmap) +
                    " for start, end: " + startBitmap + ", " + endBitmap);
        }
        if (startDrawable != null && endDrawable != null && !startBitmap.sameAs(endBitmap)) {
            ViewOverlay overlay = useParentOverlay ?
                    ((ViewGroup) view.getParent()).getOverlay() : view.getOverlay();
            if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
                overlay.add(endDrawable);
            }
            overlay.add(startDrawable);
            // The transition works by placing the end drawable under the start drawable and
            // gradually fading out the start drawable. So it's not really a cross-fade, but rather
            // a reveal of the end scene over time. Also, animate the bounds of both drawables
            // to mimic the change in the size of the view itself between scenes.
            ObjectAnimator anim;
            if (mFadeBehavior == FADE_BEHAVIOR_OUT_IN) {
                // Fade out completely halfway through the transition
                anim = ObjectAnimator.ofInt(startDrawable, "alpha", 255, 0, 0);
            } else {
                anim = ObjectAnimator.ofInt(startDrawable, "alpha", 0);
            }
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    // TODO: some way to auto-invalidate views based on drawable changes? callbacks?
                    view.invalidate(startDrawable.getBounds());
                }
            });
            ObjectAnimator anim1 = null;
            if (mFadeBehavior == FADE_BEHAVIOR_OUT_IN) {
                // start fading in halfway through the transition
                anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 0, 1);
            } else if (mFadeBehavior == FADE_BEHAVIOR_CROSSFADE) {
                anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
            }
            if (Transition.DBG) {
                Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " +
                        startValues + ", " + endValues);
            }
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    ViewOverlay overlay = useParentOverlay ?
                            ((ViewGroup) view.getParent()).getOverlay() : view.getOverlay();
                    overlay.remove(startDrawable);
                    if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
                        overlay.remove(endDrawable);
                    }
                }
            });
            AnimatorSet set = new AnimatorSet();
            set.playTogether(anim);
            if (anim1 != null) {
                set.playTogether(anim1);
            }
            if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE && !startBounds.equals(endBounds)) {
                if (Transition.DBG) {
                    Log.d(LOG_TAG, "animating from startBounds to endBounds: " +
                            startBounds + ", " + endBounds);
                }
                Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds",
                        sRectEvaluator, startBounds, endBounds);
                set.playTogether(anim2);
                if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE) {
                    // TODO: How to handle resizing with a CROSSFADE (vs. REVEAL) effect
                    // when we are animating the view directly?
                    Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
                            sRectEvaluator, startBounds, endBounds);
                    set.playTogether(anim3);
                }
            }
            return set;
        } else {
            return null;
        }
    
public intgetFadeBehavior()
Returns the fading behavior of the animation.

return
This crossfade object.
see
#setFadeBehavior(int)

        return mFadeBehavior;
    
public intgetResizeBehavior()
Returns the resizing behavior of the animation.

return
This crossfade object.
see
#setResizeBehavior(int)

        return mResizeBehavior;
    
public android.transition.CrossfadesetFadeBehavior(int fadeBehavior)
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.


    // TODO: Add fade/resize behaviors to xml resources

                                        
        
        if (fadeBehavior >= FADE_BEHAVIOR_CROSSFADE && fadeBehavior <= FADE_BEHAVIOR_OUT_IN) {
            mFadeBehavior = fadeBehavior;
        }
        return this;
    
public android.transition.CrossfadesetResizeBehavior(int resizeBehavior)
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.

        if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) {
            mResizeBehavior = resizeBehavior;
        }
        return this;