Странные проблемы с переключателем вида после анимации объектного аниматора

У меня есть два представления LinearLayout, которые содержат несколько текстов редактирования и флажки для ввода информации о пользователе (имя, адрес электронной почты и т. д.). Когда проверка не проходит проверку в одном из этих полей, отображается исчезнувшее текстовое представление, показывающее ошибку проверки.

Я заключил два макета в ViewSwitcher и анимирую между двумя представлениями, используя класс ObjectAnimator. (Поскольку код должен поддерживать более старые версии Android, я фактически использую для этого библиотеку обратной совместимости nineoldandroids).

Основная часть работы выполняется в моем методе switchToChild.

Если я переворачиваю представления более двух раз, то начинаю сталкиваться со странными ошибками.

Во-первых, хотя отображается правильное дочернее представление аниматора представления, кажется, что другое представление имеет фокус, и я могу щелкнуть представления под текущим. Я решил эту проблему, добавив viewSwitcher.bringChildToFront в конце первой анимации.

Однако, когда я делаю это и выполняю проверку на втором представлении, «исчезнувший» вид, который я теперь установил как видимый, не отображается (как будто линейный макет никогда не измеряется повторно). Вот подмножество файла XML:

<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/TitleBar"
    android:scrollbarAlwaysDrawVerticalTrack="true"
    android:scrollbarStyle="outsideOverlay"
    android:scrollbars="vertical" >

    <ViewSwitcher
        android:id="@+id/switcher"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/page_1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

        <!-- Lots of subviews here -->

        <LinearLayout
            android:id="@+id/page_2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

И это основной способ переключения между представлениями:

private void switchToChild(final int child) {
  final ViewSwitcher viewSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
  if (viewSwitcher.getDisplayedChild() != child) {
    final Interpolator accelerator = new AccelerateInterpolator();
    final Interpolator decelerator = new DecelerateInterpolator();
    final View visibleView;
    final View invisibleView;
    switch (child) {
      case 0:
        visibleView = findViewById(R.id.page_2);
        invisibleView = findViewById(R.id.page_1);
        findViewById(R.id.next).setVisibility(View.VISIBLE);
        findViewById(R.id.back).setVisibility(View.GONE);
        break;
      case 1:
      default:
        visibleView = findViewById(R.id.page_1);
        invisibleView = findViewById(R.id.page_2);
        findViewById(R.id.back).setVisibility(View.VISIBLE);
        findViewById(R.id.next).setVisibility(View.GONE);
        break;
    }
    final ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleView, "rotationY", 0f, 90f).setDuration(250);
    visToInvis.setInterpolator(accelerator);

    final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleView, "rotationY", -90f, 0f).setDuration(250);
    invisToVis.setInterpolator(decelerator);

    visToInvis.addListener(new AnimatorListenerAdapter() {

      @Override
      public void onAnimationEnd(Animator anim) {
        viewSwitcher.showNext();
        invisToVis.start();
        viewSwitcher.bringChildToFront(invisibleView); // If I don't do this the old view can have focus

      }
    });
    visToInvis.start();

  }
}

У кого-нибудь есть идеи? Это действительно сбивает меня с толку!


person Barry Irvine    schedule 11.04.2012    source источник


Ответы (1)


Похоже, лучшим решением было вообще не использовать переключатель вида, а вместо этого эффективно создать свой собственный, объявив FrameLayout вокруг двух страниц и отключив видимость второй страницы.

Метод switchToChild (который мне, вероятно, следует переименовать, чтобы переключиться на страницу и фактически передать значение 1 или 2) просто устанавливает видимость соответствующих представлений во время анимации:

private void switchToChild(final int child) {
  final Interpolator accelerator = new AccelerateInterpolator();
  final Interpolator decelerator = new DecelerateInterpolator();
  final View visibleView;
  final View invisibleView;
  switch (child) {
  case 0:
    visibleView = findViewById(R.id.page_2);
    invisibleView = findViewById(R.id.page_1);
    findViewById(R.id.next).setVisibility(View.VISIBLE);
    findViewById(R.id.back).setVisibility(View.GONE);
    break;
  case 1:
  default:
    visibleView = findViewById(R.id.page_1);
    invisibleView = findViewById(R.id.page_2);
    findViewById(R.id.back).setVisibility(View.VISIBLE);
    findViewById(R.id.next).setVisibility(View.GONE);
    break;
  }
  if (invisibleView.getVisibility() != View.VISIBLE) {
    final ObjectAnimator visToInvis = ObjectAnimator.ofFloat(visibleView, "rotationY", 0f, 90f).setDuration(250);
    visToInvis.setInterpolator(accelerator);

    final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(invisibleView, "rotationY", -90f, 0f).setDuration(250);
    invisToVis.setInterpolator(decelerator);

    visToInvis.addListener(new AnimatorListenerAdapter() {
      @Override
      public void onAnimationEnd(Animator anim) {
        visibleView.setVisibility(View.GONE);
        invisibleView.setVisibility(View.VISIBLE);

        invisToVis.start();

      }
    });
    visToInvis.start();
  }

}
person Barry Irvine    schedule 29.04.2012