3

This is not a question, more like sharing with others a problem I encountered and how I resolved it.
Basically, I was trying to create a ViewAnimator, who would create additional children in response to user clicks.
To clean up after I have animated the next View in, I put

outAnimation.setAnimationListener(listener);

and in AnimationListener

public void onAnimationEnd(Animation animation) {
    viewAnimator.removeView(out);
}

Now, the problem with above approach is, immediately after onAnimationEnd, it throws a NullPointerException. Basically, it means, ViewAnimator is still using child view that is being animated out to draw. Since I have removed it, there is null there. I have done my research, and basically, it appears this is a known bug. See: Android Animation is not finished on onAnimationEnd

To resolve this, I have modified layout.

<ViewAnimator
    android:id="@+id/animator"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <FrameLayout
        android:id="@+id/container1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </FrameLayout>

    <FrameLayout
        android:id="@+id/container2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </FrameLayout>
</ViewAnimator>

and onAnimationEnd I can safely call container.removeAllViews(). To animate a new view in, I select the hidden container and

container.addView(newView);
animator.setDisplayedChild(animator.indexOfChild(container));

I will be happy to see your comments and advice.

Community
  • 1
  • 1
Mirbek Samiev
  • 67
  • 1
  • 7

2 Answers2

4

I've run into this problem and used the view's post method to wait until the animation is really done:

      public void onAnimationEnd(Animation animation) {
        //Wait until the container has finished rendering to remove the items.
        view.post(new Runnable() {
          @Override
          public void run() {
            //remove view here
          }
        });
      }
dmon
  • 30,048
  • 8
  • 87
  • 96
  • I did try similar approach, `postDelayed(Runnable task, int delayMillis).` In my case it triggered inAnimation again for some weird reason. – Mirbek Samiev Apr 02 '12 at 23:33
2

I solved it. I have inAnimation and outAnimation. SO:

@Override
public void onAnimationEnd(Animation animation) {

    if(animationsFinished < 2) animationsFinished++;
    else{

        this.setInAnimation(null);  // Skipping this will cause trouble
        this.setOutAnimation(null); // Skipping this will cause trouble

        flipper.post(new Runnable(){

            @Override
            public void run() {
                flipper.removeView(previous);
            }

        });

        animationsFinished = 0;

    }


}