我认为您的问题是,当您在每次动画重复时更改全局变量间隔大小时,正在重复的动画不是查看您的变量,而是当您说时传递给它的原始整数: new RotateAnimation(间隔大小,间隔大小,pivotX,pivotY);
也就是说,动画将始终具有 -25,因为它是用它构建的,它不关心或知道您的 intervalSize var 的后续更改。
为了实现理想的目标,您可以执行以下操作:
@Override
public void onAnimationRepeat(Animation animation) {
if (intervalSize == 0){
animation.cancel();
} else {
((RotationAnimation)animation).setFromDegress(intervalSize);
((RotationAnimation)animation).setToDegress(intervalSize);
}
}
但是,可惜的是,RotationAnimation 上的这些属性似乎没有设置方法。因此,您可以使用 onAnimationEndEvent 创建具有新的 intervalSizeValue 的新动画。如:
使用 onAnimationEnd 事件,而不是有一个重复的动画,有一个一次性的动画。一旦结束,onAnimationEnd 事件应该使用新的 intervalSize 构造一个新的 RotationAnimation。
这是一个工作示例,它以您指定的方式从典型的 Android HelloWorld 应用程序中为 textview 设置动画:
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();
}
});
}
}