Android rotates the image, I cannot set the end position of the image in onAnimationEnd ()

I want to rotate the image from 30 degrees for every click on the button.

In the first click, I can set up the animation correctly, but I will not be able to update the position of the image after the animation. When I clicked on the button again, the animation will start from the starting position of the image, and not from the end 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 arose because of how I update the position in onAnimationEnd ().

ps: sorry for my bad english ...

+8
android rotation animation imageview
source share
1 answer

The problem is that your animation does not affect the same object as the rotation of the matrix. That is, you are animating the rotation of the ImageView, but then you set the rotation of the image inside this ImageView. For example, the first time the image is rotated, ImageView rotates from 0 to 30 degrees, and then remains rotated 30 degrees due to the call to setFillAfter (true). Then the onAnimationEnd () handler starts, which rotates the internal image by 30 degrees. This effectively skips the image until it rotates 60 degrees, as seen by the user (30 for presentation, 30 for bitmap). Then the next time the animation starts, it rotates the view from 0 to 30 degrees, with the inner image still being rotated 30 degrees. This makes him look at the user as if he is spinning 30 to 60 degrees. Then you apply another rotation on the inner image when this animation ends, as a result, the image rotates 60 degrees and the image rotates (again) 30 degrees, so the image now visually rotates 90 degrees.

And so on.

There are various ways to solve this problem, but one simple way - not to touch two different objects - just work with ImageView. Instead of rotating from 0 to 30 each time, rotate from any current rotation to this value plus 30 degrees. You can remove the onAnimationEnd () handler because you no longer need to rotate the image inside the view.

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); } 

This code assumes an instance variable currentRotation, which is used to track the last degrees the view has been rotated. Its a bit more involved if you allow the user to click the average animation, but not too complicated.

By the way, this is much simpler in the animation system in 3.0; Now the view has the "rotation" property, and you can start animating this property and track its current value. But the above approach should work for older versions.

+15
source share

All Articles