动态更改RotateAnimations参数

时间:2012-09-13 18:04:25

标签: android animation

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

        }
    });

任何人都可以请我这样做吗?

提前致谢:)

1 个答案:

答案 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();
            }
        });
    }
}