Crossfadepublic 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}. |
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_CROSSFADEFlag 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_REVEALFlag 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_INFlag 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_NONEFlag 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_SCALEFlag 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. |
Methods Summary |
---|
public void | captureEndValues(TransitionValues transitionValues)
captureValues(transitionValues);
| public void | captureStartValues(TransitionValues transitionValues)
captureValues(transitionValues);
| private void | captureValues(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.Animator | createAnimator(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 int | getFadeBehavior()Returns the fading behavior of the animation.
return mFadeBehavior;
| public int | getResizeBehavior()Returns the resizing behavior of the animation.
return mResizeBehavior;
| public android.transition.Crossfade | setFadeBehavior(int fadeBehavior)Sets the type of fading animation that will be run, one of
{@link #FADE_BEHAVIOR_CROSSFADE} and {@link #FADE_BEHAVIOR_REVEAL}.
// 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.Crossfade | setResizeBehavior(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}.
if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) {
mResizeBehavior = resizeBehavior;
}
return this;
|
|