我想在每次点击按钮时将图像视图从 30 度旋转.
I want to rotate an imageview from 30 degrees on each click on a button.
在第一个 clic 上,我可以正确设置动画,但我无法成功更新动画后的 imageview 位置.当我再次单击按钮时,动画从 imageview 的原始位置开始,而不是从第一个动画之后的最终位置开始.
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.
这是我的代码:
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() 中实现位置的方式.
I think the problem came from the way i actualize the position in the onAnimationEnd().
ps:对不起,我的英语不好......
ps : sorry for my bad english...
问题是你的动画没有影响你的矩阵旋转相同的对象.也就是说,您正在为 ImageView 对象的旋转设置动画,但随后您正在设置该 ImageView 对象内的图像的旋转.因此,例如,第一次旋转它时,ImageView 从 0 度旋转到 30 度,然后由于调用 setFillAfter(true) 而保持在 30 度的旋转.然后 onAnimationEnd() 处理程序运行,它将内部图像旋转 30 度.这有效地将图像跳转到 60 度的旋转,如用户所见(视图为 30,位图为 30).然后下一次动画运行时,它将视图从 0 度旋转到 30 度,而内部图像仍保持 30 度的旋转.这让用户看起来像是从 30 度旋转到 60 度.然后在动画结束时对内部图像应用另一个旋转,最终图像旋转到 60 度,视图(再次)旋转到 30 度,因此图像现在视觉上旋转到 90 度.
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.
等等.
有不同的方法来处理这个问题,但一种简单的方法是避免影响两个不同的对象 - 只需使用 ImageView.不是每次都从 0 旋转到 30,而是从当前旋转的任何值旋转到该值加上 30 度.您可以删除 onAnimationEnd() 处理程序,因为您将不再需要在视图内旋转图像.
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.
turn() 的结果代码要简单得多:
The resulting code for turn() is much simpler:
public void turn()
{
RotateAnimation anim = new RotateAnimation(currentRotation, currentRotation + 30,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
currentRotation = (currentRotation + 30) % 360;
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(1000);
anim.setFillEnabled(true);
anim.setFillAfter(true);
turnImg.startAnimation(anim);
}
此代码假定 currentRotation 的实例变量用于跟踪视图旋转到的最后角度.如果您允许用户单击动画中间,它会涉及更多,但不会太难.
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.
顺便说一句,这在 3.0 的动画系统中要简单得多;现在 View 上有一个旋转"属性,您可以在该属性上运行动画,它可以跟踪自己的当前值.但上述方法应该适用于旧版本.
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.
这篇关于Android 旋转 imageview,我无法在 onAnimationEnd() 中设置 imageview 的最终位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!