是否可以在 android 运行时更改 RotateAnimation 的值?

发布于 2024-12-11 16:52:14 字数 84 浏览 0 评论 0原文

我正在使用 RotateAnimation,我想在动画运行时更改动画,例如,更改“toDegrees”参数,从而使动画更短或更长。

谢谢。

I'm using RotateAnimation and i want to change the animation while it's running, for example, changing the "toDegrees" parameter and thous making the animation shorter or longer.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我很OK 2024-12-18 16:52:14

这可以帮助您(只需将 getter 和 setter 添加到所需字段)

package com.test;


import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.Transformation;

/**
 * An animation that controls the rotation of an object. This rotation takes
 * place int the X-Y plane. You can specify the point to use for the center of
 * the rotation, where (0,0) is the top left point. If not specified, (0,0) is
 * the default rotation point.
 * 
 */
public class MyRotateAnimation extends Animation {
    private float mFromDegrees;
    private float mToDegrees;

    private int mPivotXType = ABSOLUTE;
    private int mPivotYType = ABSOLUTE;
    private float mPivotXValue = 0.0f;
    private float mPivotYValue = 0.0f;

    private float mPivotX;
    private float mPivotY;

    /**
     * Constructor used when a RotateAnimation is loaded from a resource.
     * 
     * @param context Application context to use
     * @param attrs Attribute set from which to read values
     */
    public ZenRotateAnimation(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    /**
     * Constructor to use when building a RotateAnimation from code.
     * Default pivotX/pivotY point is (0,0).
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     */
    public MyRotateAnimation(float fromDegrees, float toDegrees) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mPivotX = 0.0f;
        mPivotY = 0.0f;
    }

    /**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotX The X coordinate of the point about which the object is
     *        being rotated, specified as an absolute number where 0 is the left
     *        edge.
     * @param pivotY The Y coordinate of the point about which the object is
     *        being rotated, specified as an absolute number where 0 is the top
     *        edge.
     */
    public MyRotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXType = ABSOLUTE;
        mPivotYType = ABSOLUTE;
        mPivotXValue = pivotX;
        mPivotYValue = pivotY;
    }

    /**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotXType Specifies how pivotXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotXValue The X coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        left edge. This value can either be an absolute number if
     *        pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     * @param pivotYType Specifies how pivotYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotYValue The Y coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        top edge. This value can either be an absolute number if
     *        pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     */
    public MyRotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
            int pivotYType, float pivotYValue) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXValue = pivotXValue;
        mPivotXType = pivotXType;
        mPivotYValue = pivotYValue;
        mPivotYType = pivotYType;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);

        if (mPivotX == 0.0f && mPivotY == 0.0f) {
            t.getMatrix().setRotate(degrees);
        } else {
            t.getMatrix().setRotate(degrees, mPivotX, mPivotY);
        }
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
        mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
    }

    /**
     * @return the mFromDegrees
     */
    public synchronized float getmFromDegrees() {
        return mFromDegrees;
    }

    /**
     * @param mFromDegrees the mFromDegrees to set
     */
    public synchronized void setmFromDegrees(float mFromDegrees) {
        this.mFromDegrees = mFromDegrees;
    }

    /**
     * @return the mToDegrees
     */
    public synchronized float getmToDegrees() {
        return mToDegrees;
    }

    /**
     * @param mToDegrees the mToDegrees to set
     */
    public synchronized void setmToDegrees(float mToDegrees) {
        this.mToDegrees = mToDegrees;
    }

    /**
     * @return the mPivotXType
     */
    public synchronized int getmPivotXType() {
        return mPivotXType;
    }

    /**
     * @param mPivotXType the mPivotXType to set
     */
    public synchronized void setmPivotXType(int mPivotXType) {
        this.mPivotXType = mPivotXType;
    }

    /**
     * @return the mPivotYType
     */
    public synchronized int getmPivotYType() {
        return mPivotYType;
    }

    /**
     * @param mPivotYType the mPivotYType to set
     */
    public synchronized void setmPivotYType(int mPivotYType) {
        this.mPivotYType = mPivotYType;
    }

    /**
     * @return the mPivotXValue
     */
    public synchronized float getmPivotXValue() {
        return mPivotXValue;
    }

    /**
     * @param mPivotXValue the mPivotXValue to set
     */
    public synchronized void setmPivotXValue(float mPivotXValue) {
        this.mPivotXValue = mPivotXValue;
    }

    /**
     * @return the mPivotYValue
     */
    public synchronized float getmPivotYValue() {
        return mPivotYValue;
    }

    /**
     * @param mPivotYValue the mPivotYValue to set
     */
    public synchronized void setmPivotYValue(float mPivotYValue) {
        this.mPivotYValue = mPivotYValue;
    }

    /**
     * @return the mPivotX
     */
    public synchronized float getmPivotX() {
        return mPivotX;
    }

    /**
     * @param mPivotX the mPivotX to set
     */
    public synchronized void setmPivotX(float mPivotX) {
        this.mPivotX = mPivotX;
    }

    /**
     * @return the mPivotY
     */
    public synchronized float getmPivotY() {
        return mPivotY;
    }

    /**
     * @param mPivotY the mPivotY to set
     */
    public synchronized void setmPivotY(float mPivotY) {
        this.mPivotY = mPivotY;
    }


}

This can help you (just added getters and setters to needed fields)

package com.test;


import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.Transformation;

/**
 * An animation that controls the rotation of an object. This rotation takes
 * place int the X-Y plane. You can specify the point to use for the center of
 * the rotation, where (0,0) is the top left point. If not specified, (0,0) is
 * the default rotation point.
 * 
 */
public class MyRotateAnimation extends Animation {
    private float mFromDegrees;
    private float mToDegrees;

    private int mPivotXType = ABSOLUTE;
    private int mPivotYType = ABSOLUTE;
    private float mPivotXValue = 0.0f;
    private float mPivotYValue = 0.0f;

    private float mPivotX;
    private float mPivotY;

    /**
     * Constructor used when a RotateAnimation is loaded from a resource.
     * 
     * @param context Application context to use
     * @param attrs Attribute set from which to read values
     */
    public ZenRotateAnimation(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    /**
     * Constructor to use when building a RotateAnimation from code.
     * Default pivotX/pivotY point is (0,0).
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     */
    public MyRotateAnimation(float fromDegrees, float toDegrees) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mPivotX = 0.0f;
        mPivotY = 0.0f;
    }

    /**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotX The X coordinate of the point about which the object is
     *        being rotated, specified as an absolute number where 0 is the left
     *        edge.
     * @param pivotY The Y coordinate of the point about which the object is
     *        being rotated, specified as an absolute number where 0 is the top
     *        edge.
     */
    public MyRotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXType = ABSOLUTE;
        mPivotYType = ABSOLUTE;
        mPivotXValue = pivotX;
        mPivotYValue = pivotY;
    }

    /**
     * Constructor to use when building a RotateAnimation from code
     * 
     * @param fromDegrees Rotation offset to apply at the start of the
     *        animation.
     * 
     * @param toDegrees Rotation offset to apply at the end of the animation.
     * 
     * @param pivotXType Specifies how pivotXValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotXValue The X coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        left edge. This value can either be an absolute number if
     *        pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     * @param pivotYType Specifies how pivotYValue should be interpreted. One of
     *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
     *        Animation.RELATIVE_TO_PARENT.
     * @param pivotYValue The Y coordinate of the point about which the object
     *        is being rotated, specified as an absolute number where 0 is the
     *        top edge. This value can either be an absolute number if
     *        pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
     *        otherwise.
     */
    public MyRotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
            int pivotYType, float pivotYValue) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;

        mPivotXValue = pivotXValue;
        mPivotXType = pivotXType;
        mPivotYValue = pivotYValue;
        mPivotYType = pivotYType;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);

        if (mPivotX == 0.0f && mPivotY == 0.0f) {
            t.getMatrix().setRotate(degrees);
        } else {
            t.getMatrix().setRotate(degrees, mPivotX, mPivotY);
        }
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
        mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
    }

    /**
     * @return the mFromDegrees
     */
    public synchronized float getmFromDegrees() {
        return mFromDegrees;
    }

    /**
     * @param mFromDegrees the mFromDegrees to set
     */
    public synchronized void setmFromDegrees(float mFromDegrees) {
        this.mFromDegrees = mFromDegrees;
    }

    /**
     * @return the mToDegrees
     */
    public synchronized float getmToDegrees() {
        return mToDegrees;
    }

    /**
     * @param mToDegrees the mToDegrees to set
     */
    public synchronized void setmToDegrees(float mToDegrees) {
        this.mToDegrees = mToDegrees;
    }

    /**
     * @return the mPivotXType
     */
    public synchronized int getmPivotXType() {
        return mPivotXType;
    }

    /**
     * @param mPivotXType the mPivotXType to set
     */
    public synchronized void setmPivotXType(int mPivotXType) {
        this.mPivotXType = mPivotXType;
    }

    /**
     * @return the mPivotYType
     */
    public synchronized int getmPivotYType() {
        return mPivotYType;
    }

    /**
     * @param mPivotYType the mPivotYType to set
     */
    public synchronized void setmPivotYType(int mPivotYType) {
        this.mPivotYType = mPivotYType;
    }

    /**
     * @return the mPivotXValue
     */
    public synchronized float getmPivotXValue() {
        return mPivotXValue;
    }

    /**
     * @param mPivotXValue the mPivotXValue to set
     */
    public synchronized void setmPivotXValue(float mPivotXValue) {
        this.mPivotXValue = mPivotXValue;
    }

    /**
     * @return the mPivotYValue
     */
    public synchronized float getmPivotYValue() {
        return mPivotYValue;
    }

    /**
     * @param mPivotYValue the mPivotYValue to set
     */
    public synchronized void setmPivotYValue(float mPivotYValue) {
        this.mPivotYValue = mPivotYValue;
    }

    /**
     * @return the mPivotX
     */
    public synchronized float getmPivotX() {
        return mPivotX;
    }

    /**
     * @param mPivotX the mPivotX to set
     */
    public synchronized void setmPivotX(float mPivotX) {
        this.mPivotX = mPivotX;
    }

    /**
     * @return the mPivotY
     */
    public synchronized float getmPivotY() {
        return mPivotY;
    }

    /**
     * @param mPivotY the mPivotY to set
     */
    public synchronized void setmPivotY(float mPivotY) {
        this.mPivotY = mPivotY;
    }


}
一张白纸 2024-12-18 16:52:14

接受的答案对我不起作用。所需要的是当前动画的“平滑”延续而不会出现故障。相反,我稍微修改了 RotationAnimation 类以返回“当前使用”的度数,然后可以使用它:

/**
* Allows you to fetch the currently 'used' animation degrees so you can create a new animator
* out of it, allowing smooth animation
*/
class AdjustableRotationAnimation extends Animation {
 private float mFromDegrees;
 private float mToDegrees;
 private volatile float mAnimatedDegrees;

 private int mPivotXType = ABSOLUTE;
 private int mPivotYType = ABSOLUTE;
 private float mPivotXValue = 0.0f;
 private float mPivotYValue = 0.0f;

 private float mPivotX;
 private float mPivotY;

 public AdjustableRotationAnimation(Context context, AttributeSet attrs) {
   super(context, attrs);

 }

 public AdjustableRotationAnimation(float fromDegrees, float toDegrees) {
   mFromDegrees = fromDegrees;
   mToDegrees = toDegrees;
   mPivotX = 0.0f;
   mPivotY = 0.0f;
 }

 public AdjustableRotationAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
   mFromDegrees = fromDegrees;
   mToDegrees = toDegrees;

   mPivotXType = ABSOLUTE;
   mPivotYType = ABSOLUTE;
   mPivotXValue = pivotX;
   mPivotYValue = pivotY;
 }


  public AdjustableRotationAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
                                   int pivotYType, float pivotYValue) {
    mFromDegrees = fromDegrees;
    mToDegrees = toDegrees;

    mPivotXValue = pivotXValue;
    mPivotXType = pivotXType;
    mPivotYValue = pivotYValue;
    mPivotYType = pivotYType;
  }

  @Override
  protected void applyTransformation(float interpolatedTime, Transformation t) {
    mAnimatedDegrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
    float scale = getScaleFactor();

    if (mPivotX == 0.0f && mPivotY == 0.0f) {
      t.getMatrix().setRotate(mAnimatedDegrees);
    } else {
     t.getMatrix().setRotate(mAnimatedDegrees, mPivotX * scale, mPivotY * scale);
   }
 }

 @Override
 public void initialize(int width, int height, int parentWidth, int parentHeight) {
   super.initialize(width, height, parentWidth, parentHeight);
   mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
   mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
 }

 public synchronized float getAnimatedDegrees() {
   return mAnimatedDegrees;
 }
}

这就是我使用它的方式:

  currentRotate = currentRotate % DEGREES_360;
  int animationDuration = 400;

  if (rotateAnimation != null && !rotateAnimation.hasEnded()) {
    rotateAnimation = new AdjustableRotationAnimation(rotateAnimation.getAnimatedDegrees(), currentRotate, Animation.RELATIVE_TO_SELF, CENTER, Animation.RELATIVE_TO_SELF, CENTER);
    rotateAnimation.setInterpolator(new DecelerateInterpolator());
    rotateAnimation.setDuration(animationDuration);
    rotateAnimation.setFillAfter(true);
    rotateAnimation.setAnimationListener(this);
  } else {
    rotateAnimation = new AdjustableRotationAnimation(lastRotation, currentRotate, Animation.RELATIVE_TO_SELF, CENTER, Animation.RELATIVE_TO_SELF, CENTER);
    rotateAnimation.setInterpolator(new DecelerateInterpolator());
    rotateAnimation.setDuration(animationDuration);
    rotateAnimation.setFillAfter(true);
    rotateAnimation.setAnimationListener(this);
  }

  viewToRotate.startAnimation(rotateAnimation);

这将每次创建一个新的动画,但是它会给人延续和动画的感觉将从“取消”的地方顺利继续。

The accepted answer didn't work for me. What's needed is 'smooth' continuation of the current animation without getting a glitch. Instead I modified the RotationAnimation class slightly to return the 'currently used' degrees, which can then be used:

/**
* Allows you to fetch the currently 'used' animation degrees so you can create a new animator
* out of it, allowing smooth animation
*/
class AdjustableRotationAnimation extends Animation {
 private float mFromDegrees;
 private float mToDegrees;
 private volatile float mAnimatedDegrees;

 private int mPivotXType = ABSOLUTE;
 private int mPivotYType = ABSOLUTE;
 private float mPivotXValue = 0.0f;
 private float mPivotYValue = 0.0f;

 private float mPivotX;
 private float mPivotY;

 public AdjustableRotationAnimation(Context context, AttributeSet attrs) {
   super(context, attrs);

 }

 public AdjustableRotationAnimation(float fromDegrees, float toDegrees) {
   mFromDegrees = fromDegrees;
   mToDegrees = toDegrees;
   mPivotX = 0.0f;
   mPivotY = 0.0f;
 }

 public AdjustableRotationAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
   mFromDegrees = fromDegrees;
   mToDegrees = toDegrees;

   mPivotXType = ABSOLUTE;
   mPivotYType = ABSOLUTE;
   mPivotXValue = pivotX;
   mPivotYValue = pivotY;
 }


  public AdjustableRotationAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
                                   int pivotYType, float pivotYValue) {
    mFromDegrees = fromDegrees;
    mToDegrees = toDegrees;

    mPivotXValue = pivotXValue;
    mPivotXType = pivotXType;
    mPivotYValue = pivotYValue;
    mPivotYType = pivotYType;
  }

  @Override
  protected void applyTransformation(float interpolatedTime, Transformation t) {
    mAnimatedDegrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
    float scale = getScaleFactor();

    if (mPivotX == 0.0f && mPivotY == 0.0f) {
      t.getMatrix().setRotate(mAnimatedDegrees);
    } else {
     t.getMatrix().setRotate(mAnimatedDegrees, mPivotX * scale, mPivotY * scale);
   }
 }

 @Override
 public void initialize(int width, int height, int parentWidth, int parentHeight) {
   super.initialize(width, height, parentWidth, parentHeight);
   mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
   mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
 }

 public synchronized float getAnimatedDegrees() {
   return mAnimatedDegrees;
 }
}

And this is how I use it:

  currentRotate = currentRotate % DEGREES_360;
  int animationDuration = 400;

  if (rotateAnimation != null && !rotateAnimation.hasEnded()) {
    rotateAnimation = new AdjustableRotationAnimation(rotateAnimation.getAnimatedDegrees(), currentRotate, Animation.RELATIVE_TO_SELF, CENTER, Animation.RELATIVE_TO_SELF, CENTER);
    rotateAnimation.setInterpolator(new DecelerateInterpolator());
    rotateAnimation.setDuration(animationDuration);
    rotateAnimation.setFillAfter(true);
    rotateAnimation.setAnimationListener(this);
  } else {
    rotateAnimation = new AdjustableRotationAnimation(lastRotation, currentRotate, Animation.RELATIVE_TO_SELF, CENTER, Animation.RELATIVE_TO_SELF, CENTER);
    rotateAnimation.setInterpolator(new DecelerateInterpolator());
    rotateAnimation.setDuration(animationDuration);
    rotateAnimation.setFillAfter(true);
    rotateAnimation.setAnimationListener(this);
  }

  viewToRotate.startAnimation(rotateAnimation);

This would create a new animation each time, however it would give the feeling of continuation and the animation will smoothly continue from where it got 'cancelled'.

海的爱人是光 2024-12-18 16:52:14

您有 cancel() startOffsetTime()restrictDuration()。不过,我没有看到任何可以更改角度的 api,因此您可能必须启动一个新的 RotateAnitmation

You have cancel() startOffsetTime(), and restrictDuration(). I don't see any api to change the degree though, so you may have to start a new RotateAnitmation

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文