Search code examples
androidandroid-layoutandroid-animationandroid-relativelayoutobjectanimator

Android Removing View do not ends its animation


I have added childView with ObjectAnimator in RelativeLayout. Now when I remove all the child from RelativeLayout I still gets onAnimationEnd triggered.

How would I stop all the animation of childViews once I removed all the childs from RelativeLayout.

RelativeLayout container = (RelativeLayout) findViewById(R.id.container);

RelativeLayout.LayoutParams layoutParams = getCircleLayoutParam(R.dimen.game_circle_width, R.dimen.game_circle_ht);

container.addView(view, layoutParams);

ObjectAnimator scale = ObjectAnimator.ofPropertyValuesHolder(view,
        PropertyValuesHolder.ofFloat("alpha", 0f),
        PropertyValuesHolder.ofFloat("scaleY", 1f),
        PropertyValuesHolder.ofFloat("y", 0, mWindowHeight));

scale.setDuration(SPEED_TIME);
scale.start();

scale.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        //Getting triggered even after calling container.removeAllViews()
    }

    @Override
    public void onAnimationCancel(Animator animation) {
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }
});

btn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (scale != null){
                            scale.removeAllListeners();
                            scale.cancel();
                            scale.end();
                        }

                        container.removeAllViews();
                        container.invalidate();
                    }
                });

On calling container.removeAllViews() and container.invalidate() on button click. I still gets onAnimationEnd() triggered.

Any response is highly appreciated.


Solution

  • When adding a View to the container, pass the Animator as tag:

    view.setTag(scale);
    

    The OnClickListener:

    btn.setOnClickListener(new View.OnClickListener() {
    
         @Override
         public void onClick(View v) {
    
             for (int i = 0; i < container.getChildCount(); i++)
             {
                 View v = container.getChildAt(i);
                 Object o = v.getTag();
                 if (o != null && o instanceof ObjectAnimator)
                 {
                     ((ObjectAnimator)o).cancel();
                     // or ...end(), see below
                 }
             }
             container.removeAllViews();
             container.invalidate();
         }
    });
    

    Use ValueAnimator.cancel() or ValueAnimator.end() depending on which result you want to achieve, see documentation

    If the tag is already in use for some other purpose, one could keep a list with the ObjectAnimators and in the for loop run through that list.