2016-10-08 7 views
1

Androidで作成したゲームに問題があります。すべてのAndroidアニメーションがスキップされます

私のゲームはObjectAnimatorValueAnimatorスレッドの多くと協力しています。

一部のユーザーは、ゲームを再生できないようにする問題を試しています。すべてのアニメーションをスキップします。

スタミナモード(私のXperia Z3)がアクティブになっているにもかかわらず、このバグを再現することができますが、一部のユーザーにはS7 Edgeでもこのバグがあります。詳しくは、StaminaモードはすべてのXperiaの携帯電話に含まれるバッテリーセーバーです。

どうすればこのバグを防ぐことができますか?

答えて

1

私のアニメーションにも同様の問題がありました。アニメーションはバッテリーにとって高価なので、バッテリー節約モードではアニメーションは実行されず、アプリケーションは状態を終了状態にスキップします。 私は、アニメーションを使用しレンダリングした可能性の1つとして、ObjectAnimatorとValueAnimatorをカスタム実装に置き換えることがあります。以下は、反時計回りの方向に塗りつぶすアニメーションのカスタムサークルビューの例です。このアニメーションはバッテリー節約モードで発生します。

基本的には、アニメーションの長さを知り、1秒ごとに描画する割合を知っているので、描画してからキャンバスをクリアし、次の秒に描画の割合を描画します。これは、キャンバスをクリアして終了状態を保持しない最終状態に達するまで発生します。主な部分は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() { 
      } 
     }); 
関連する問題