Search code examples
androidandroid-animationobjectanimator

ObjectAnimator reset to initial status


What I want to achieve

  1. The custom view is initially green.
  2. When the button is clicked, the view starts to animates its color between green and white infinitely.
  3. When the button is clicked again, the view should resets its color to its initial status (green) and stops animation.

Step 2 and 3 can be applied infinitely.

Problem

My problem is that when the button is clicked while the animation is going on, the view does not reset its color to its initial status (green), instead, no matter which point the animation has reached at that moment, the view turns into the final status (white).

I have tried to use the solution from another similar question on SO, but no lucks.

Code

How I initialize my ObjectAnimator

animator = ObjectAnimator.ofArgb(this, "color", WHITE);
animator.setDuration(ANIMATION_DURATION);
animator.setRepeatCount(Animation.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);

The custom view class has a private member of Animator.AnimatorListener, which implements onAnimationEnd(), and I attach it to the animator in startAnimation(), detach it from the animator in onAnimationEnd() because the solution I referenced above said so.

private Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        animation.removeListener(this);
        animation.setDuration(0);
        ((ObjectAnimator) animation).reverse();
    }
};

public void startAnimation(){
    animator.addListener(animatorListener);
    animator.setDuration(ANIMATION_DURATION);
    animator.start();
}

public void stopAnimation(){
    animator.end();
    // animatorListener.onAnimationEnd() will be called here
}

I'm not sure if it's the best way to achieve my goal, and any suggestions will be appreciated.


Solution

  • Try the following:

    public class Demo8 extends AppCompatActivity {
    
    private Button b;
    private ViewC v;
    private ObjectAnimator animator;
    
    private enum animation_state {START, CLEAR}
    
    private animation_state animation_current_state = animation_state.START;
    
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo8);
    
        b = (Button) findViewById(R.id.b);
        v = (ViewC) findViewById(R.id.v);
    
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!animator.isRunning()) {
                    CAnimator(animation_state.START);
                } else {
                    CAnimator(animation_state.CLEAR);
                }
            }
        });
    
        animator = ObjectAnimator.ofArgb(v, "background", Color.WHITE);
        animator.setDuration(1000);
        animator.setRepeatCount(Animation.INFINITE);
        animator.setRepeatMode(ObjectAnimator.REVERSE);
        animator.addListener(animatorListener);
    }
    
    private Animator.AnimatorListener animatorListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationStart(Animator animation, boolean isReverse) {
    
        }
    
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            Log.e("End" , "***********True");
            animation.removeListener(this);
    
        }
    
        @Override
        public void onAnimationRepeat(Animator animation) {
            super.onAnimationRepeat(animation);
            Log.e("Repeat" , "***********True");
          }
    
    };
    
    
    private void CAnimator(animation_state s) {
        animation_current_state = s;
        if (s == animation_state.START) {
            animator.start();
        } else if (s == animation_state.CLEAR) {
            animator.cancel();
            v.setBackground(Color.GREEN);
        }
    }
    
    }
    

    ViewC (Custom View):

    public class ViewC extends View {
    
    
    private static final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private int color;
    
    public ViewC(Context context) {
        super(context);
    }
    
    public ViewC(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        color = Color.GREEN;
    }
    
    public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    public ViewC(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    
    final RectF rect = new RectF(2.5f * 20,
                0.5f * (getHeight() - 5), getWidth() - 2.5f * 20,
                0.5f * (getHeight() + 5));
        paint.setColor(color);
        canvas.drawRect(rect, paint);
    }
    
    public void setBackground(int color){
        this.color = color;
        invalidate();
    }
    
    
        }
    

    layout demo8.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    
    <com.example.admin.machinelearning.ViewC // Change this to your package
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:id="@+id/v">
    </com.example.admin.machinelearning.ViewC>
    
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/b"
        android:text="Button"/>
    
    </LinearLayout>