OnDraw ViewAnimator генерирует исключение NullPointerException, если вы удаляете дочерний элемент в onAnimationEnd - PullRequest
3 голосов
/ 03 апреля 2012

Это не вопрос, скорее, как поделиться с другими проблемой, с которой я столкнулся и как я ее решил.
По сути, я пытался создать ViewAnimator, который создавал бы дополнительных дочерних элементов в ответ на щелчки пользователей.
Для очистки после того, как я анимировал следующий просмотр, я поставил

outAnimation.setAnimationListener(listener);

и в AnimationListener

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

Теперь проблема с вышеуказанным подходом заключается в том, что сразу после onAnimationEnd он генерирует исключение NullPointerException. По сути, это означает, что ViewAnimator все еще использует дочернее представление, которое анимируется для рисования. Так как я удалил это, там есть нуль. Я сделал свое исследование, и в основном, похоже, это известная ошибка. См .: Анимация Android не завершена на анимацииEnd

Чтобы решить эту проблему, я изменил макет.

<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>

и onAnimationEnd я могу смело звонить container.removeAllViews(). Чтобы анимировать новый вид, я выбираю скрытый контейнер и

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

Буду рад видеть ваши комментарии и советы.

Ответы [ 2 ]

4 голосов
/ 03 апреля 2012

Я столкнулся с этой проблемой и использовал метод представления post, чтобы дождаться, когда анимация действительно будет выполнена:

      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
          }
        });
      }
1 голос
/ 18 июля 2012

Я решил это.У меня есть в анимации и вне анимации.ТАК:

@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;

    }


}
...