我的所有Android动画都会被跳过

时间:2016-10-08 23:24:38

标签: android background task objectanimator

我在Android上创建的游戏存在问题。

我的游戏正在使用大量 ObjectAnimator ValueAnimator 线程

有些用户尝试了一个让游戏无法播放的问题:跳过所有动画

当Stamina模式(在我的Xperia Z3上)被激活时,我可以重现这个错误,但是一些用户也有S7 Edge的这个错误。有关信息,Stamina模式是所有Xperia手机中都包含的节电器。

如何防止此错误?

1 个答案:

答案 0 :(得分:1)

我的动画也有类似的问题。动画对于电池来说是昂贵的,因此在节电模式下,动画不会被执行并且应用程序会将状态跳到最终状态。 我使用并确实渲染动画的一种可能性是用自定义实现替换ObjectAnimator和ValueAnimator。以下是我以逆时针方向填充的自定义圆形视图的示例。此动画在节电模式下发生。

基本上,我发现动画的持续时间是什么,然后我知道每秒要完成的绘图百分比,我绘制然后清除画布然后在下一秒绘制绘图的百分比。这种情况发生,直到我到达结束状态,当我不清除画布并保持结束状态。主要部分是onDraw方法。

public class AnimatedCircleView extends View {
  private Interpolator INTERPOLATOR = new AccelerateDecelerateInterpolator();

  @IntDef({START, END, ANIMATING})
  @Retention(RetentionPolicy.SOURCE)
  public @interface State {
  }

  private static final int START = 0;
  private static final int END = 1;
  private static final int ANIMATING = 2;

  private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  private final RectF mRect = new RectF();

  @State private int mState = START;
  private long mAnimationStartTime = 0;
  private long mDuration = 0;
  private Listener mListener = null;

  public AnimatedCircleView(Context context) {
    super(context);
  }

  public AnimatedCircleView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public void startCircleAnimation(long durationMillis, Listener listener) {
    mDuration = durationMillis;
    mAnimationStartTime = System.currentTimeMillis();
    mState = ANIMATING;
    mListener = listener;
    invalidate();
  }

  @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mRect.left = 0;
    mRect.right = w;
    mRect.top = 0;
    mRect.bottom = h;
  }

  @Override protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mState == START) {
      // Draw nothing.
      return;
    }

    float percentToDraw;
    if (mState == ANIMATING) {
      float currentAnimationTime = System.currentTimeMillis() - mAnimationStartTime;//Get how much animation time is remaining
      float percentAnimationTime = currentAnimationTime / mDuration;//So now you how much percent you need to draw
      if (percentAnimationTime >= 1f) { //If percent is greater than 100%, you have reached the end
        percentToDraw = 1f;
        mState = END;
        if (mListener != null) mListener.onAnimationEnd();
      } else {
        percentToDraw = INTERPOLATOR.getInterpolation(percentAnimationTime);//Else apply the interpolator
      }
    } else {
      // END state
      percentToDraw = 1f;
    }
    float sweepValue = 360f * percentToDraw; //Multiply the final value of the filled circle with percentToDraw, so you know how much to draw.
    float sweepAngle = -sweepValue; //Draw anti clockwise
    canvas.drawArc(mRect, -90, sweepAngle, false, mPaint); //Draw on canvas

    if (mState == ANIMATING) {
      postInvalidateOnAnimation(); // Clear the drawing as animation is happening
    }
  }

  public interface Listener {
    void onAnimationEnd();
  }
}

在xml中包含此自定义视图,如下所示:

<com.example.sunny.BatteryCircle.AnimatedCircleView
        android:id="@+id/cvAnimatedCircleView"
        android:layout_centerVertical="true"
        android:layout_width="45dp"
        android:layout_height="45dp" />

现在您可以按如下方式从活动中调用动画:

AnimatedCircleView animatedCircleView = (AnimatedCircleView) findViewById(R.id.cvAnimatedCircleView);
        animatedCircleView.startCircleAnimation(2000, new AnimatedCircleView.Listener() {
            @Override public void onAnimationEnd() {
            }
        });