Android旋转imageview,我无法在onAnimationEnd()中设置imageview的最终位置
我想在每次单击按钮时将图像视图旋转 30 度。
在第一个 CLIC 上,我可以正确设置动画,但在动画后无法成功更新图像视图位置。当我再次单击按钮时,动画从图像视图的原始位置开始,而不是从第一个动画之后的最终位置开始。
这是我的代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
turnImg = (ImageView) findViewById(R.id.imageViewturnImg );
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.imgTurn);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
turnImg .setImageBitmap(bmp);
Button buttonok = (Button) findViewById(R.id.buttonok);
buttonok.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
turn();
}
});
}
public void turn()
{
float degrees = 30;
RotateAnimation anim = new RotateAnimation(0, degrees,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(300);
anim.setFillEnabled(true);
anim.setFillAfter(true);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation arg0) {
Matrix mat = turnImg.getImageMatrix();
mat.postRotate(30,turnImg.getWidth()/2, turnImg.getHeight()/2);
turnImg.setScaleType(ScaleType.MATRIX);
turnImg.setImageMatrix(mat);
}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationStart(Animation animation) {}
});
turnImg.startAnimation(anim);
}
我认为问题来自于我在 onAnimationEnd() 中实现位置的方式。
PS:抱歉我的英语不好......
I want to rotate an imageview from 30 degrees on each click on a button.
On the first clic, i can set the animation properly but i can't succeed to update the imageview position after the animation. When i clicked again on the button, the animation start from the original position of the imageview and not from the final position after the first animation.
Here is my code :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
turnImg = (ImageView) findViewById(R.id.imageViewturnImg );
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.imgTurn);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
turnImg .setImageBitmap(bmp);
Button buttonok = (Button) findViewById(R.id.buttonok);
buttonok.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
turn();
}
});
}
public void turn()
{
float degrees = 30;
RotateAnimation anim = new RotateAnimation(0, degrees,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(300);
anim.setFillEnabled(true);
anim.setFillAfter(true);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation arg0) {
Matrix mat = turnImg.getImageMatrix();
mat.postRotate(30,turnImg.getWidth()/2, turnImg.getHeight()/2);
turnImg.setScaleType(ScaleType.MATRIX);
turnImg.setImageMatrix(mat);
}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationStart(Animation animation) {}
});
turnImg.startAnimation(anim);
}
I think the problem came from the way i actualize the position in the onAnimationEnd().
ps : sorry for my bad english...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是您的动画不会影响与矩阵旋转相同的对象。也就是说,您正在为 ImageView 对象的旋转设置动画,但随后您正在设置该 ImageView 对象内的图像的旋转。因此,例如,第一次旋转 ImageView 时,它会从 0 度旋转到 30 度,然后由于调用 setFillAfter(true) 而保持 30 度的旋转。然后运行 onAnimationEnd() 处理程序,将内部图像旋转 30 度。这有效地将图像旋转 60 度,如用户所见(视图为 30 度,位图为 30 度)。然后,下次动画运行时,它将视图从 0 度旋转到 30 度,内部图像仍保持 30 度的旋转。这使得用户看起来像是从 30 度旋转到 60 度。然后,当动画完成时,您对内部图像应用另一次旋转,最终图像旋转到 60 度,视图(再次)旋转到 30 度,因此图像现在在视觉上旋转到 90 度。
等等。
有不同的方法可以处理这个问题,但一种简单的方法是避免影响两个不同的对象 - 只需使用 ImageView 即可。不要每次从 0 旋转到 30,而是从当前旋转值旋转到该值加 30 度。您可以删除 onAnimationEnd() 处理程序,因为您不再需要在视图内旋转图像。
turn() 的结果代码要简单得多:
此代码假设有一个 currentRotation 实例变量,用于跟踪视图旋转到的最后度数。
如果您允许用户单击动画中间,则涉及更多一点,但也不是太困难。
顺便说一句,这在3.0的动画系统中要简单得多;现在视图上有一个“旋转”属性,您可以在该属性上运行动画,并且它可以跟踪自己的当前值。但上述方法应该适用于旧版本。
The problem is that your animation is not affecting the same object as your matrix rotation. That is, you are animating the rotation of the ImageView object, but then you are setting the rotation of the image that is within that ImageView object. So, for example, the first time you rotate it, the ImageView rotates from 0 to 30 degrees, and then remains at a rotation of 30 degrees due to the call to setFillAfter(true). Then the onAnimationEnd() handler runs, which rotates the internal image by 30 degrees. This effectively jumps the image to a rotation of 60 degrees, as seen by the user (30 for the View, 30 for the bitmap). Then the next time the animation runs, it rotates the view from 0 to 30 degrees, with the internal image still at its rotation of 30 degrees. This makes it look to the user like it's rotating from 30 to 60 degrees. Then you apply another rotation on the internal image when that animation finishes, ending up with the image rotated to 60 degrees and the view rotated (again) to 30 degrees, so the image is now visually rotated to 90 degrees.
And so on.
There are different ways to handle this problem, but one simple way is to avoid affecting the two different objects - just work with the ImageView. Instead of rotating from 0 to 30 each time, rotate from whatever the current rotation is to that value plus 30 degrees. You can remove the onAnimationEnd() handler, because you will no longer need to rotate the image inside the view.
The resulting code for turn() is much simpler:
This code assumes an instance variable of currentRotation, which is used to track the last degrees the view was rotated to.
Its a bit more involved if you allow the user to click mid-animation, but not too difficult.
By the way, this is much simpler in the animation system in 3.0; there is now a 'rotation' property on View, and you can run an animation on that property and it can track its own current value. But the approach above should work for older releases.