Можно ли изменить значения RotateAnimation в Android во время его работы? - PullRequest
1 голос
/ 25 октября 2011

Я использую RotateAnimation и хочу изменить анимацию во время ее работы, например, изменить параметр "toDegrees" и сделать анимацию короче или длиннее.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 18 ноября 2011

Это может вам помочь (только что добавили геттеры и сеттеры в нужные поля)

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;
    }


}
0 голосов
/ 26 сентября 2016

Принятый ответ не сработал для меня.Нужно «плавное» продолжение текущей анимации без сбоев.Вместо этого я немного изменил класс 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);

Это будетсоздайте новую анимацию каждый раз, однако это даст ощущение продолжения, и анимация будет плавно продолжаться с того места, где она была «отменена».

0 голосов
/ 25 октября 2011

У вас есть cancel () startOffsetTime () и restrictDuration () . Я не вижу API для изменения степени, поэтому вам, возможно, придется начать новую RotateAnitmation

...