0

我已经定义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) {

        }
    });

任何人都可以请我怎样才能做到这一点?

提前致谢:)

4

1 回答 1

1

我认为您的问题是,当您在每次动画重复时更改全局变量间隔大小时,正在重复的动画不是查看您的变量,而是当您说时传递给它的原始整数: 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();
            }
        });
    }
}
于 2012-09-13T20:10:11.133 回答