あなたの問題は、アニメーションが繰り返されるたびにグローバル変数の間隔サイズを変更しているときに、繰り返されるアニメーションが変数を見ているのではなく、あなたが言ったときに渡されたプリミティブな int を見ていることだと思います: new RotateAnimation( intervalSize、intervalSize、pivotX、pivotY);
つまり、アニメーションは常に -25 で構成されているため、intervalSize 変数へのその後の変更を気にしたり認識したりしません。
理想的には、次のようなことができます。
@Override
public void onAnimationRepeat(Animation animation) {
if (intervalSize == 0){
animation.cancel();
} else {
((RotationAnimation)animation).setFromDegress(intervalSize);
((RotationAnimation)animation).setToDegress(intervalSize);
}
}
しかし残念なことに、RotationAnimation にこれらの属性のセッター メソッドがあるようには見えません。そのため、onAnimationEndEvent を使用して、新しい intervalSizeValue を持つ新しいアニメーションを作成する可能性が残ります。次のように:
onAnimationEnd イベントを使用し、アニメーションを繰り返すのではなく、1 回限りのアニメーションにします。終了すると、onAnimationEnd イベントは、新しい intervalSize で新しい RotationAnimation を構築する必要があります。
指定した方法で典型的な Android HelloWorld アプリからテキストビューをアニメーション化する実際の例を次に示します。
package com.example.rotationtest;
import android.os.Bundle;
import android.app.Activity;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// the textView we will rotate
tv = (TextView) this.findViewById(R.id.textView1);
/***
* we want to have the correct measured size of the view we are going to animate
* as we want to do a rotation around it's centerpoint.
* But, we cant get the measured size of a view until Layout has happened...
* So use a LayoutListener to know when layout is done
* But, beware that this is often called back on more than once,
* so remove the listener after it is called first time
*/
tv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
initAnimation();
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// above is deprecated. in API16+ use tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
private int mRotationAbsDegrees = 25;
private int mCurrentFromDegrees;
private int mCurrentToDegrees;
private void initAnimation(){
mCurrentFromDegrees = -1 * mRotationAbsDegrees;
mCurrentToDegrees = mRotationAbsDegrees;
makeNewAnimation();
}
private void makeNewAnimation(){
RotateAnimation r = new RotateAnimation(mCurrentFromDegrees, mCurrentToDegrees, tv.getMeasuredWidth()/2, tv.getMeasuredHeight()/2);
r.setDuration(3000); // TODO: might want to reduce the time as we get closer to zero mRotationAbsDegrees
r.setStartOffset(0);
//r.setRepeatMode(RotateAnimation.REVERSE);
//r.setRepeatCount(RotateAnimation.INFINITE);
tv.startAnimation(r);
r.setAnimationListener(new AnimationListener() {
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
// if we have run down the mRotationAbsDegrees to zero, stop animating
if (mRotationAbsDegrees <= 0){
return;
}
if (mCurrentFromDegrees < 0){
// reverse the from to
mCurrentFromDegrees = -1*mCurrentFromDegrees;
mCurrentToDegrees = -1*mCurrentToDegrees;
} else {
// reduce the mRotationAbsDegrees
mRotationAbsDegrees--;
mCurrentFromDegrees = -1 * mRotationAbsDegrees;
mCurrentToDegrees = mRotationAbsDegrees;
}
makeNewAnimation();
}
});
}
}