我在约束布局中有两个图像。我想将左图移到右边,然后直接落在另一个上面。两幅图像的大小和位置相对相同。一个在右边,一个在左边。当我使用移动动画时,它会略微偏离图像。
代码:
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>
答案 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();