Search in sources :

Example 1 with RectEvaluator

use of com.transitionseverywhere.utils.RectEvaluator in project Transitions-Everywhere by andkulikov.

the class Crossfade method createAnimator.

@Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
    if (startValues == null || endValues == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        return null;
    }
    if (sRectEvaluator == null) {
        sRectEvaluator = new RectEvaluator();
    }
    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)) {
        ViewGroupOverlayUtils.addCrossfadeOverlay(useParentOverlay, view, mFadeBehavior, startDrawable, endDrawable);
        // 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) {
                ViewGroupOverlayUtils.removeCrossfadeOverlay(useParentOverlay, view, mFadeBehavior, startDrawable, 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;
    }
}
Also used : RectEvaluator(com.transitionseverywhere.utils.RectEvaluator) Rect(android.graphics.Rect) ObjectAnimator(android.animation.ObjectAnimator) AnimatorSet(android.animation.AnimatorSet) BitmapDrawable(android.graphics.drawable.BitmapDrawable) ValueAnimator(android.animation.ValueAnimator) SurfaceView(android.view.SurfaceView) TextureView(android.view.TextureView) View(android.view.View) Bitmap(android.graphics.Bitmap) ObjectAnimator(android.animation.ObjectAnimator) Animator(android.animation.Animator) ValueAnimator(android.animation.ValueAnimator) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter)

Example 2 with RectEvaluator

use of com.transitionseverywhere.utils.RectEvaluator in project Transitions-Everywhere by andkulikov.

the class ChangeBounds method createAnimator.

@Override
public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
    if (startValues == null || endValues == null) {
        return null;
    }
    if (sRectEvaluator == null) {
        sRectEvaluator = new RectEvaluator();
    }
    Map<String, Object> startParentVals = startValues.values;
    Map<String, Object> endParentVals = endValues.values;
    ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
    ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
    if (startParent == null || endParent == null) {
        return null;
    }
    final View view = endValues.view;
    if (parentMatches(startParent, endParent)) {
        Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
        Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
        final int startLeft = startBounds.left;
        final int endLeft = endBounds.left;
        final int startTop = startBounds.top;
        final int endTop = endBounds.top;
        final int startRight = startBounds.right;
        final int endRight = endBounds.right;
        final int startBottom = startBounds.bottom;
        final int endBottom = endBounds.bottom;
        final int startWidth = startRight - startLeft;
        final int startHeight = startBottom - startTop;
        final int endWidth = endRight - endLeft;
        final int endHeight = endBottom - endTop;
        Rect startClip = (Rect) startValues.values.get(PROPNAME_CLIP);
        Rect endClip = (Rect) endValues.values.get(PROPNAME_CLIP);
        int numChanges = 0;
        if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) {
            if (startLeft != endLeft || startTop != endTop)
                ++numChanges;
            if (startRight != endRight || startBottom != endBottom)
                ++numChanges;
        }
        if ((startClip != null && !startClip.equals(endClip)) || (startClip == null && endClip != null)) {
            ++numChanges;
        }
        if (numChanges > 0) {
            Animator anim;
            if (!mResizeClip || (startClip == null && endClip == null)) {
                ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startRight, startBottom);
                if (numChanges == 2) {
                    if (startWidth == endWidth && startHeight == endHeight) {
                        anim = AnimatorUtils.ofPointF(view, POSITION_PROPERTY, getPathMotion(), startLeft, startTop, endLeft, endTop);
                    } else {
                        ViewBounds viewBounds = new ViewBounds(view);
                        Animator topLeftAnimator = AnimatorUtils.ofPointF(viewBounds, TOP_LEFT_PROPERTY, getPathMotion(), startLeft, startTop, endLeft, endTop);
                        Animator bottomRightAnimator = AnimatorUtils.ofPointF(viewBounds, BOTTOM_RIGHT_PROPERTY, getPathMotion(), startRight, startBottom, endRight, endBottom);
                        AnimatorSet set = new AnimatorSet();
                        set.playTogether(topLeftAnimator, bottomRightAnimator);
                        set.addListener(viewBounds);
                        anim = set;
                    }
                } else if (startLeft != endLeft || startTop != endTop) {
                    anim = AnimatorUtils.ofPointF(view, TOP_LEFT_ONLY_PROPERTY, getPathMotion(), startLeft, startTop, endLeft, endTop);
                } else {
                    anim = AnimatorUtils.ofPointF(view, BOTTOM_RIGHT_ONLY_PROPERTY, getPathMotion(), startRight, startBottom, endRight, endBottom);
                }
            } else {
                int maxWidth = Math.max(startWidth, endWidth);
                int maxHeight = Math.max(startHeight, endHeight);
                ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startLeft + maxWidth, startTop + maxHeight);
                Animator positionAnimator = null;
                if (startLeft != endLeft || startTop != endTop) {
                    positionAnimator = AnimatorUtils.ofPointF(view, POSITION_PROPERTY, getPathMotion(), startLeft, startTop, endLeft, endTop);
                }
                final Rect finalClip = endClip;
                if (startClip == null) {
                    startClip = new Rect(0, 0, startWidth, startHeight);
                }
                if (endClip == null) {
                    endClip = new Rect(0, 0, endWidth, endHeight);
                }
                ObjectAnimator clipAnimator = null;
                if (!startClip.equals(endClip)) {
                    ViewUtils.setClipBounds(view, startClip);
                    clipAnimator = ObjectAnimator.ofObject(view, ChangeClipBounds.VIEW_CLIP_BOUNDS, sRectEvaluator, startClip, endClip);
                    clipAnimator.addListener(new AnimatorListenerAdapter() {

                        private boolean mIsCanceled;

                        @Override
                        public void onAnimationCancel(Animator animation) {
                            mIsCanceled = true;
                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            if (!mIsCanceled) {
                                ViewUtils.setClipBounds(view, finalClip);
                                ViewUtils.setLeftTopRightBottom(view, endLeft, endTop, endRight, endBottom);
                            }
                        }
                    });
                }
                anim = TransitionUtils.mergeAnimators(positionAnimator, clipAnimator);
            }
            if (view.getParent() instanceof ViewGroup) {
                final ViewGroup parent = (ViewGroup) view.getParent();
                ViewGroupUtils.suppressLayout(parent, true);
                TransitionListener transitionListener = new TransitionListenerAdapter() {

                    boolean mCanceled = false;

                    @Override
                    public void onTransitionCancel(Transition transition) {
                        ViewGroupUtils.suppressLayout(parent, false);
                        mCanceled = true;
                    }

                    @Override
                    public void onTransitionEnd(Transition transition) {
                        if (!mCanceled) {
                            ViewGroupUtils.suppressLayout(parent, false);
                        }
                    }

                    @Override
                    public void onTransitionPause(Transition transition) {
                        ViewGroupUtils.suppressLayout(parent, false);
                    }

                    @Override
                    public void onTransitionResume(Transition transition) {
                        ViewGroupUtils.suppressLayout(parent, true);
                    }
                };
                addListener(transitionListener);
            }
            return anim;
        }
    } else {
        sceneRoot.getLocationInWindow(tempLocation);
        int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X) - tempLocation[0];
        int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y) - tempLocation[1];
        int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X) - tempLocation[0];
        int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y) - tempLocation[1];
        // TODO: also handle size changes: check bounds and animate size changes
        if (startX != endX || startY != endY) {
            final int width = view.getWidth();
            final int height = view.getHeight();
            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            view.draw(canvas);
            final BitmapDrawable drawable = new BitmapDrawable(sceneRoot.getContext().getResources(), bitmap);
            drawable.setBounds(startX, startY, startX + width, startY + height);
            Animator anim;
            anim = AnimatorUtils.ofPointF(drawable, DRAWABLE_ORIGIN_PROPERTY, getPathMotion(), startX, startY, endX, endY);
            if (anim != null) {
                final float alpha = view.getAlpha();
                view.setAlpha(0);
                ViewOverlayUtils.addOverlay(sceneRoot, drawable);
                anim.addListener(new AnimatorListenerAdapter() {

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        ViewOverlayUtils.removeOverlay(sceneRoot, drawable);
                        view.setAlpha(alpha);
                    }
                });
            }
            return anim;
        }
    }
    return null;
}
Also used : RectEvaluator(com.transitionseverywhere.utils.RectEvaluator) Rect(android.graphics.Rect) ViewGroup(android.view.ViewGroup) ObjectAnimator(android.animation.ObjectAnimator) Canvas(android.graphics.Canvas) AnimatorSet(android.animation.AnimatorSet) BitmapDrawable(android.graphics.drawable.BitmapDrawable) View(android.view.View) Bitmap(android.graphics.Bitmap) ObjectAnimator(android.animation.ObjectAnimator) Animator(android.animation.Animator) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter)

Example 3 with RectEvaluator

use of com.transitionseverywhere.utils.RectEvaluator in project Transitions-Everywhere by andkulikov.

the class ChangeClipBounds method createAnimator.

@Override
public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
    if (startValues == null || endValues == null || !startValues.values.containsKey(PROPNAME_CLIP) || !endValues.values.containsKey(PROPNAME_CLIP)) {
        return null;
    }
    Rect start = (Rect) startValues.values.get(PROPNAME_CLIP);
    Rect end = (Rect) endValues.values.get(PROPNAME_CLIP);
    if (start == null && end == null) {
        // No animation required since there is no clip.
        return null;
    }
    if (start == null) {
        start = (Rect) startValues.values.get(PROPNAME_BOUNDS);
    } else if (end == null) {
        end = (Rect) endValues.values.get(PROPNAME_BOUNDS);
    }
    if (start.equals(end)) {
        return null;
    }
    ViewUtils.setClipBounds(endValues.view, start);
    RectEvaluator evaluator = new RectEvaluator(new Rect());
    return ObjectAnimator.ofObject(endValues.view, VIEW_CLIP_BOUNDS, evaluator, start, end);
}
Also used : Rect(android.graphics.Rect) RectEvaluator(com.transitionseverywhere.utils.RectEvaluator)

Aggregations

Rect (android.graphics.Rect)3 RectEvaluator (com.transitionseverywhere.utils.RectEvaluator)3 Animator (android.animation.Animator)2 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)2 AnimatorSet (android.animation.AnimatorSet)2 ObjectAnimator (android.animation.ObjectAnimator)2 Bitmap (android.graphics.Bitmap)2 BitmapDrawable (android.graphics.drawable.BitmapDrawable)2 View (android.view.View)2 ValueAnimator (android.animation.ValueAnimator)1 Canvas (android.graphics.Canvas)1 SurfaceView (android.view.SurfaceView)1 TextureView (android.view.TextureView)1 ViewGroup (android.view.ViewGroup)1