从一个布局动画到另一个布局的视图

9

请查看附带的图片以便更好地理解。

翻译动画效果正常,但它只是在同一个视图内进行动画。 我想让视图从一个布局飞到另一个布局。

动画应该如何工作

我尝试了这个答案中提供的方法。(在同一布局中进行动画)

public class Animations {
        public Animation fromAtoB(float fromX, float fromY, float toX, float toY, int speed){


            Animation fromAtoB = new TranslateAnimation(
                    Animation.ABSOLUTE, //from xType
                    fromX,
                    Animation.ABSOLUTE, //to xType
                    toX,
                    Animation.ABSOLUTE, //from yType
                    fromY,
                    Animation.ABSOLUTE, //to yType
                    toY
            );

            fromAtoB.setDuration(speed);
            fromAtoB.setInterpolator(new AnticipateOvershootInterpolator(1.0f));

            return fromAtoB;
        }

我不确定,但您可以尝试使用场景 https://developer.android.com/training/transitions/index.html?hl=ru - HotIceCream
2个回答

7
我最近使用动画器做了类似的动画。一般来说,视图不会显示在其父视图之外,视图将被其父视图的边界裁剪。因此,诀窍是在要进行动画的原始视图(fromView)上方放置一个新视图(shuttleView),对齐它们,并将shuttleView缩放/平移成目标视图(toView)。
这个解决方案支持缩放和平移,以下是示例:https://www.dropbox.com/s/iom95o93076h52f/device-2016-06-03-111557.mp4?dl=0 以下是代码:
activity_main.xml
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:layout_alignParentTop="true"
    android:background="@android:color/holo_blue_dark">

    <TextView
        android:id="@+id/itemTo"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_margin="10dp"
        android:background="@android:color/holo_blue_bright"
        android:text="to"/>

</LinearLayout>


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:layout_alignParentBottom="true"
    android:background="@android:color/holo_blue_dark">

    <TextView
        android:layout_width="90dp"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:background="@android:color/holo_blue_bright" />

    <TextView
        android:id="@+id/itemFrom"
        android:layout_width="90dp"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:text="from"
        android:background="@android:color/holo_blue_bright" />

    <TextView
        android:layout_width="90dp"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:background="@android:color/holo_blue_bright" />
</LinearLayout>

<View
    android:id="@+id/shuttle"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@android:color/holo_blue_bright"/>

活动类:

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;
    }
}

您可以在animatorSet监听器的不同动画阶段中进行许多自定义操作,以控制出现和消失的内容。希望这对您有所帮助。

谢谢。看起来很有前途。我会去尝试一下 :) 奖励很快就会到你手上。 - Lakhwinder Singh Dhillon
成功了!但是我必须进行一些微小的更改,因为如果目标布局为空,它将不起作用。所以,我不得不在目标布局中通过编程方式添加虚拟视图。非常感谢。 - Lakhwinder Singh Dhillon

4
如果有人正在寻找更简单的解决方案,您可以使用过渡框架: https://developer.android.com/training/transitions/index.html 为了将一个视图从一个父视图动画移到另一个父视图,有一个特殊的转换ChangeTransform: https://developer.android.com/reference/android/transition/ChangeTransform.html 这里是一个小例子:
animatedView = View.inflate(ActivityMain.this, R.layout.item, firstParent);
animatedView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
Transition move = new ChangeTransform()
                        .addTarget(animatedView)
                        .setDuration(2000));
TransitionManager.beginDelayedTransition(rootParent, move);
firstParent.removeView(animatedView);
animatedView.setPadding(2,2,2,2);
animatedView.setElevation(4);
secondParent.addView(animatedView, 0);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接