将imageview移动到另一个图像视图,移动动画未正确排列

时间:2018-03-09 23:19:55

标签: android

我在约束布局中有两个图像。我想将左图移到右边,然后直接落在另一个上面。两幅图像的大小和位置相对相同。一个在右边,一个在左边。当我使用移动动画时,它会略微偏离图像。

代码:

Animation img = new TranslateAnimation(Animation.ABSOLUTE, playerTwoCard.getLeft(), Animation.ABSOLUTE, playerTwoCard.getTop());

XML

<android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <ImageView
            android:id="@+id/playerOneCardTest"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="8dp"
            app:srcCompat="@mipmap/club_ace" />

        <ImageView
            android:id="@+id/playerTwoCardTest"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginRight="8dp"
            android:layout_marginTop="8dp"
            app:srcCompat="@mipmap/spade_ace" />



    </android.support.constraint.ConstraintLayout>

1 个答案:

答案 0 :(得分:0)

我试图将一个ImageView移动到另一个ImageView上。目标ImageView和目标图像视图不需要具有相同的宽度和高度。我实现这一目标的解决方案是使用ObjectAnimator。

首先,像这样设置AnimationViewTranslator。

public class AnimationViewTranslator {
private static final int DEFAULT_DURATION = 1000;
private static final int DEFAULT_DURATION_DISAPPEAR = 200;
private View mTarget;
private View mDest;

private float originX;
private float originY;
private float destX;
private float destY;

private int mCircleDuration = DEFAULT_DURATION;
private int mMoveDuration = DEFAULT_DURATION;
private int mDisappearDuration = DEFAULT_DURATION_DISAPPEAR;

private WeakReference<Activity> mContextReference;
private Bitmap mBitmap;
private ImageView mImageView;
private Animator.AnimatorListener mAnimationListener;

public AnimationViewTranslator() {
}

public AnimationViewTranslator attachActivity(Activity activity) {
    mContextReference = new WeakReference<Activity>(activity);
    return this;
}

public AnimationViewTranslator setTargetView(View view) {
    mTarget = view;
    setOriginRect(mTarget.getWidth(), mTarget.getHeight());
    return this;
}

private AnimationViewTranslator setOriginRect(float x, float y) {
    originX = x;
    originY = y;
    return this;
}

private AnimationViewTranslator setDestRect(float x, float y) {
    destX = x;
    destY = y;
    return this;
}

public AnimationViewTranslator setDestView(View view) {
    mDest = view;
    setDestRect(mDest.getWidth(), mDest.getWidth());
    return this;
}

public AnimationViewTranslator setBorderWidth(int width) {
    mBorderWidth = width;
    return this;
}

public AnimationViewTranslator setBorderColor(int color) {
    mBorderColor = color;
    return this;
}

public AnimationViewTranslator setCircleDuration(int duration) {
    mCircleDuration = duration;
    return this;
}

public AnimationViewTranslator setMoveDuration(int duration) {
    mMoveDuration = duration;
    return this;
}

private boolean prepare() {
    if (mContextReference.get() != null) {
        ViewGroup decoreView = (ViewGroup) mContextReference.get().getWindow().getDecorView();

        mBitmap = drawViewToBitmap(mTarget, mTarget.getWidth(), mTarget.getHeight());
        if (mImageView == null)
            mImageView = new ImageView(mContextReference.get());
        mImageView.setImageBitmap(mBitmap);

        int[] src = new int[2];
        mTarget.getLocationOnScreen(src);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mTarget.getWidth(), mTarget.getHeight());
        params.setMargins(src[0], src[1], 0, 0);
        if (mImageView.getParent() == null)
            decoreView.addView(mImageView, params);
    }
    return true;
}

public void startAnimation() {

    if (prepare()) {
        getAvatarRevealAnimator().start();
    }
}

private AnimatorSet getAvatarRevealAnimator() {
    final float endRadius = Math.max(destX, destY) / 2;
    final float startRadius = Math.max(originX, originY);

    Animator mRevealAnimator = ObjectAnimator.ofFloat(mImageView, "scaleX", startRadius, endRadius * 1.05f, endRadius * 0.9f, endRadius);
    mRevealAnimator.setInterpolator(new AccelerateInterpolator());

    final float scaleFactor = 1.5f;
    Animator scaleAnimatorY = ObjectAnimator.ofFloat(mImageView, View.SCALE_Y, 1, 1, scaleFactor, 1);
    Animator scaleAnimatorX = ObjectAnimator.ofFloat(mImageView, View.SCALE_X, 1, 1, scaleFactor, 1);
    Animator alphaAnimator = ObjectAnimator.ofFloat(mImageView, View.ALPHA, 0, 1);

    AnimatorSet animatorCircleSet = new AnimatorSet();
    animatorCircleSet.setDuration(mCircleDuration);
    animatorCircleSet.playTogether(scaleAnimatorX, scaleAnimatorY, alphaAnimator);
    animatorCircleSet.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            if (mAnimationListener != null)
                mAnimationListener.onAnimationStart(animation);
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            int[] src = new int[2];
            int[] dest = new int[2];
            mImageView.getLocationOnScreen(src);
            Log.i("SOURCE", src[0] + " " +src[1]);
            mDest.getLocationOnScreen(dest);

            float y = mImageView.getY();
            float x = mImageView.getX();
            Animator translatorX = ObjectAnimator.ofFloat(mImageView, View.X, x, x + dest[0] - (src[0] + (originX * scaleFactor - 2 * endRadius * scaleFactor) / 2) + (0.5f * destX - scaleFactor * endRadius));
            translatorX.setInterpolator(new TimeInterpolator() {
                @Override
                public float getInterpolation(float input) {
                    return (float) (-Math.pow(input - 1, 2) + 1f);
                }
            });
            Animator translatorY = ObjectAnimator.ofFloat(mImageView, View.Y, y, y + dest[1] - (src[1] + (originY * scaleFactor - 2 * endRadius * scaleFactor) / 2) + (0.5f * destY - scaleFactor * endRadius));
            translatorY.setInterpolator(new LinearInterpolator());

            AnimatorSet animatorMoveSet = new AnimatorSet();
            animatorMoveSet.playTogether(translatorX, translatorY);
            animatorMoveSet.setDuration(mMoveDuration);

            AnimatorSet animatorDisappearSet = new AnimatorSet();
            Animator disappearAnimatorY = ObjectAnimator.ofFloat(mImageView, View.SCALE_Y, 1, 0);
            Animator disappearAnimatorX = ObjectAnimator.ofFloat(mImageView, View.SCALE_X, 1, 0);
            Animator disappearAlphaAnimator = ObjectAnimator.ofFloat(mImageView, View.ALPHA, 1, 0);
            animatorDisappearSet.setDuration(mDisappearDuration);
            animatorDisappearSet.playTogether(disappearAnimatorX, disappearAnimatorY, disappearAlphaAnimator);


            AnimatorSet total = new AnimatorSet();
            total.playSequentially(animatorMoveSet, animatorDisappearSet);
            total.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    if (mAnimationListener != null)
                        mAnimationListener.onAnimationEnd(animation);
                    reset();
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            total.start();
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

    return animatorCircleSet;
}

private Bitmap drawViewToBitmap(View view, int width, int height) {
    Drawable drawable = new BitmapDrawable();
    Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(dest);
    drawable.setBounds(new Rect(0, 0, width, height));
    drawable.draw(c);
    view.draw(c);
    return dest;
}

private void reset() {
    mBitmap.recycle();
    mBitmap = null;
    if (mImageView.getParent() != null)
        ((ViewGroup) mImageView.getParent()).removeView(mImageView);
    mImageView = null;
}

public AnimationViewTranslator setAnimationListener(Animator.AnimatorListener listener) {
    mAnimationListener = listener;
    return this;
}}

设置AnimationViewTranslator后,再使用这样的动画。

new AnimationViewTranslator().attachActivity(activity).setTargetView(targetView).setMoveDuration(430).setDestView(destView).setAnimationListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {

        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    }).startAnimation();