Animate a view from one Layout to other Layout

后端 未结 2 362
时光说笑
时光说笑 2021-02-03 12:15

Check attached image for easy explanation.

Translate animation works but it animates inside the same view. I want view to fly out from one layout to other.

2条回答
  •  不思量自难忘°
    2021-02-03 13:05

    I recently did animation of a similar kind using Animators. In general, views will not display themselves outside of their parents' boundaries, the view will be cut by it's parent's boundaries. That's why, the trick is to place a new view (shuttleView) on top of the origin view (fromView) that you want to animate, align them, and animate scaling/translation of shuttleView into a target view (toView).

    This solution supports both scaling and translation, here is sample: https://www.dropbox.com/s/iom95o93076h52f/device-2016-06-03-111557.mp4?dl=0

    Here is the code:

    activity_main.xml

    
    
        
    
    
    
    
    
    
        
    
        
    
        
    
    
    
    

    Activity class:

    public class MainActivity extends AppCompatActivity {
        public static final int ANIMATION_SPEED = 3000;
        private RelativeLayout rootView;
        private View fromView, toView, shuttleView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            rootView = (RelativeLayout) findViewById(R.id.rootView);
            fromView = findViewById(R.id.itemFrom);
            toView = findViewById(R.id.itemTo);
            shuttleView = findViewById(R.id.shuttle);
    
            fromView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Rect fromRect = new Rect();
                    Rect toRect = new Rect();
                    fromView.getGlobalVisibleRect(fromRect);
                    toView.getGlobalVisibleRect(toRect);
    
                    AnimatorSet animatorSet = getViewToViewScalingAnimator(rootView, shuttleView, fromRect, toRect, ANIMATION_SPEED, 0);
    
                    animatorSet.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {
                            shuttleView.setVisibility(View.VISIBLE);
                            fromView.setVisibility(View.INVISIBLE);
                        }
    
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            shuttleView.setVisibility(View.GONE);
                            fromView.setVisibility(View.VISIBLE);
                        }
    
                        @Override
                        public void onAnimationCancel(Animator animation) {
    
                        }
    
                        @Override
                        public void onAnimationRepeat(Animator animation) {
    
                        }
                    });
                    animatorSet.start();
                }
            });
        }
    
    
        public static AnimatorSet getViewToViewScalingAnimator(final RelativeLayout parentView,
                                                               final View viewToAnimate,
                                                               final Rect fromViewRect,
                                                               final Rect toViewRect,
                                                               final long duration,
                                                               final long startDelay) {
            // get all coordinates at once
            final Rect parentViewRect = new Rect(), viewToAnimateRect = new Rect();
            parentView.getGlobalVisibleRect(parentViewRect);
            viewToAnimate.getGlobalVisibleRect(viewToAnimateRect);
    
            viewToAnimate.setScaleX(1f);
            viewToAnimate.setScaleY(1f);
    
            // rescaling of the object on X-axis
            final ValueAnimator valueAnimatorWidth = ValueAnimator.ofInt(fromViewRect.width(), toViewRect.width());
            valueAnimatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    // Get animated width value update
                    int newWidth = (int) valueAnimatorWidth.getAnimatedValue();
    
                    // Get and update LayoutParams of the animated view
                    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
    
                    lp.width = newWidth;
                    viewToAnimate.setLayoutParams(lp);
                }
            });
    
            // rescaling of the object on Y-axis
            final ValueAnimator valueAnimatorHeight = ValueAnimator.ofInt(fromViewRect.height(), toViewRect.height());
            valueAnimatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    // Get animated width value update
                    int newHeight = (int) valueAnimatorHeight.getAnimatedValue();
    
                    // Get and update LayoutParams of the animated view
                    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
                    lp.height = newHeight;
                    viewToAnimate.setLayoutParams(lp);
                }
            });
    
            // moving of the object on X-axis
            ObjectAnimator translateAnimatorX = ObjectAnimator.ofFloat(viewToAnimate, "X", fromViewRect.left - parentViewRect.left, toViewRect.left - parentViewRect.left);
    
            // moving of the object on Y-axis
            ObjectAnimator translateAnimatorY = ObjectAnimator.ofFloat(viewToAnimate, "Y", fromViewRect.top - parentViewRect.top, toViewRect.top - parentViewRect.top);
    
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.setInterpolator(new DecelerateInterpolator(1f));
            animatorSet.setDuration(duration); // can be decoupled for each animator separately
            animatorSet.setStartDelay(startDelay); // can be decoupled for each animator separately
            animatorSet.playTogether(valueAnimatorWidth, valueAnimatorHeight, translateAnimatorX, translateAnimatorY);
    
            return animatorSet;
        }
    }
    

    You can do a whole bunch of customizations in terms of what appears and disappears at different stages of animation in animatorSet listener. Hope it's helpful.

提交回复
热议问题