我已定义RotateAnimation
来轮播ImageView
。所以,我想在一些重复之后停止动画。方案如下:
第一个动画从-25到25度开始,在一个动画之后,应该更改为-24到24并且反向和......当达到0到0时,这应该被取消。
int intervalSize = -25;
RotateAnimation r = new RotateAnimation(intervalSize, intervalSize, pivotX, pivotY);
r.setDuration(3000);
r.setStartOffset(0);
r.setRepeatMode(RotateAnimation.REVERSE);
r.setRepeatCount(RotateAnimation.INFINITE);
startAnimation(r);
r.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
if (intervalSize == 0)
animation.cancel();
intervalSize--;
}
@Override
public void onAnimationEnd(Animation animation) {
}
});
任何人都可以请我这样做吗?
提前致谢:)
答案 0 :(得分:1)
我认为你的问题是,当你在每次动画重复时改变你的全局变换间隔大小时,正在重复的动画不会看你的var,而是你说的时传递给它的原始整数: new RotateAnimation(intervalSize,intervalSize,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上有这些属性的setter方法。因此,您可以使用onAnimationEndEvent使用新的intervalSizeValue创建新的Animation。如:
使用onAnimationEnd事件而不是重复动画,有一次动画。一旦它结束,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();
}
});
}
}