使用 "V" 形状的动画对 ImageView 进行动画处理
Animating an ImageView with a "V" shaped animation
我正在尝试通过 "V"(上下向上)从右向左移动图像。这是一张描述我所追求的图像:
我尝试使用 ObjectAnimator
和 AnimatorSet
但我没有得到我想要得到的东西。而且很难理解为什么我会得到别的东西。
这是我当前的代码:
/**
* translateLeft = -160dp
* translateDown = 25dp
* translateUp = -25dp
*/
private void vShapedAnimation () {
AnimatorSet upDownSet = new AnimatorSet();
AnimatorSet downUpSet = new AnimatorSet();
AnimatorSet finalSet = new AnimatorSet();
ObjectAnimator rightToLeft = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2);
ObjectAnimator upDown = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateDown));
ObjectAnimator downUp = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateUp));
upDownSet.playTogether(
rightToLeft,
upDown
);
downUpSet.playTogether(
rightToLeft,
downUp
);
finalSet.playSequentially(
upDownSet,
downUpSet
);
finalSet.setDuration(300);
finalSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
animation.removeListener(this);
animation.setDuration(0);
animation.setInterpolator(new ReverseInterpolator());
animation.start();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
finalSet.start();
}
AnimatorListener
中的ReverseInterpolator
来自这里:
How to reset ObjectAnimator to it's initial status?
我打算同时稍微旋转图像。如果 "V" 可以向内弯曲一点,那就完美了。但是,如果一开始有人能帮我做基本的动画,我将不胜感激。
ObjectAnimator
有它奇怪的时刻,但我终于掌握了它(至少足以解决我自己的问题)。
要注意的是,在一系列动画中,最好始终指明起始位置和结束位置。在我写的问题中,三个ObjectAnimators
只给出了结束位置。这使得动画从奇怪的地方开始。
使用伪代码示例,如果要从A到C经过B,则需要这样写:
ObjectAnimator AtoB_X = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, A.x, B.x - A.x);
ObjectAnimator BtoC_X = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, B.x - A.x, C.x - A.x);
ObjectAnimator AtoB_Y = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, A.y, B.y - A.y);
ObjectAnimator BtoC_Y = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, B.y - A.y, C.y - A.y);
重要提示:始终使用 dp
测量值。切勿使用 px
测量值。这就是为什么在我的代码中使用 this.getResources().getDimensionPixelOffset()
。它将 dp
值转换为适合每个屏幕分辨率的 px
值。
现在,对于我的工作代码:
private void vShapedAnimation() {
AnimatorSet upDownSet = new AnimatorSet();
AnimatorSet downUpSet = new AnimatorSet();
AnimatorSet finalSet = new AnimatorSet();
ObjectAnimator rightToHalf = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, 0, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2);
ObjectAnimator halfToLeft = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft));
ObjectAnimator upDown = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, 0, this.getResources().getDimensionPixelOffset(R.dimen.translateDown));
ObjectAnimator downUp = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateDown), 0);
upDownSet.playTogether(
rightToHalf,
upDown
);
downUpSet.playTogether(
halfToLeft,
downUp
);
finalSet.playSequentially(
upDownSet,
downUpSet
);
finalSet.setInterpolator(new LinearInterpolator());
finalSet.setDuration(300);
finalSet.start();
}
我正在尝试通过 "V"(上下向上)从右向左移动图像。这是一张描述我所追求的图像:
我尝试使用 ObjectAnimator
和 AnimatorSet
但我没有得到我想要得到的东西。而且很难理解为什么我会得到别的东西。
这是我当前的代码:
/**
* translateLeft = -160dp
* translateDown = 25dp
* translateUp = -25dp
*/
private void vShapedAnimation () {
AnimatorSet upDownSet = new AnimatorSet();
AnimatorSet downUpSet = new AnimatorSet();
AnimatorSet finalSet = new AnimatorSet();
ObjectAnimator rightToLeft = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2);
ObjectAnimator upDown = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateDown));
ObjectAnimator downUp = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateUp));
upDownSet.playTogether(
rightToLeft,
upDown
);
downUpSet.playTogether(
rightToLeft,
downUp
);
finalSet.playSequentially(
upDownSet,
downUpSet
);
finalSet.setDuration(300);
finalSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
animation.removeListener(this);
animation.setDuration(0);
animation.setInterpolator(new ReverseInterpolator());
animation.start();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
finalSet.start();
}
AnimatorListener
中的ReverseInterpolator
来自这里:
How to reset ObjectAnimator to it's initial status?
我打算同时稍微旋转图像。如果 "V" 可以向内弯曲一点,那就完美了。但是,如果一开始有人能帮我做基本的动画,我将不胜感激。
ObjectAnimator
有它奇怪的时刻,但我终于掌握了它(至少足以解决我自己的问题)。
要注意的是,在一系列动画中,最好始终指明起始位置和结束位置。在我写的问题中,三个ObjectAnimators
只给出了结束位置。这使得动画从奇怪的地方开始。
使用伪代码示例,如果要从A到C经过B,则需要这样写:
ObjectAnimator AtoB_X = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, A.x, B.x - A.x);
ObjectAnimator BtoC_X = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, B.x - A.x, C.x - A.x);
ObjectAnimator AtoB_Y = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, A.y, B.y - A.y);
ObjectAnimator BtoC_Y = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, B.y - A.y, C.y - A.y);
重要提示:始终使用 dp
测量值。切勿使用 px
测量值。这就是为什么在我的代码中使用 this.getResources().getDimensionPixelOffset()
。它将 dp
值转换为适合每个屏幕分辨率的 px
值。
现在,对于我的工作代码:
private void vShapedAnimation() {
AnimatorSet upDownSet = new AnimatorSet();
AnimatorSet downUpSet = new AnimatorSet();
AnimatorSet finalSet = new AnimatorSet();
ObjectAnimator rightToHalf = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, 0, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2);
ObjectAnimator halfToLeft = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_X, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft) / 2, this.getResources().getDimensionPixelOffset(R.dimen.translateLeft));
ObjectAnimator upDown = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, 0, this.getResources().getDimensionPixelOffset(R.dimen.translateDown));
ObjectAnimator downUp = ObjectAnimator.ofFloat(this.imageView, View.TRANSLATION_Y, this.getResources().getDimensionPixelOffset(R.dimen.translateDown), 0);
upDownSet.playTogether(
rightToHalf,
upDown
);
downUpSet.playTogether(
halfToLeft,
downUp
);
finalSet.playSequentially(
upDownSet,
downUpSet
);
finalSet.setInterpolator(new LinearInterpolator());
finalSet.setDuration(300);
finalSet.start();
}