Так что же происходит?
Кажется, все работает нормально, кроме той вспышки, о которой вы упоминаете. Я взял приложение Cheese Square Криса Бейнса и сделал несколько модификаций, чтобы дублировать то, что вы видите. Нажатие FAB удаляет и добавляет вкладки.
Вот видео того, что я придумал.
Вот снимок экрана проблемы, когда TabLayout
удален. Как видите, RecyclerView
перекрывает панель приложения.
Вот снимок экрана проблемы, когда TabLayout
добавляется обратно. Здесь вы можете видеть, что RecyclerView
сдвигается вниз в свою позицию после добавления вида.
Переход макета исчезающего TabLayout
выполняется с помощью LayoutTransition
. Чтобы сделать эффективный переход, LayoutTransition
должен определить, как выглядит окончательный макет, чтобы можно было создать набор анимаций. Это требует выкладки того, как будет выглядеть экран после перехода. появляется , что окончательный макет отображается незадолго до запуска анимации. (Мое предположение.) Это может быть состояние гонки или это может быть связано с этой оговоркой :
Этот класс и связанный с ним флаг XML для контейнеров animateLayoutChanges = "true" предоставляют простую утилиту, предназначенную для автоматизации изменений в простых ситуациях. Использование LayoutTransition на нескольких уровнях иерархии вложенного представления может не работать из-за взаимосвязи различных уровней макета. Кроме того, контейнер, который прокручивается одновременно с добавлением или удалением элементов, вероятно, не является подходящим кандидатом для этой утилиты, поскольку местоположения до / после, рассчитанные с помощью LayoutTransition, могут не совпадать с фактическими местоположениями, когда анимация заканчивается из-за контейнер прокручивается при запуске анимации. Вы можете обойти эту конкретную проблему, отключив «изменяющиеся» анимации, установив для анимаций CHANGE_APPEARING и CHANGE_DISAPPEARING значение null и соответственно установив startDelay других анимаций.
Престижность и репутация тому, кто может точно выяснить, что происходит. (Эта проблема может быть артефактами, упомянутыми в следующем загадочном комментарии в коде для LayoutTransition
:)
/**
* Controls whether changing animations automatically animate the parent hierarchy as well.
* This behavior prevents artifacts when wrap_content layouts snap to the end state as the
* transition begins, causing visual glitches and clipping.
* Default value is true.
*/
private boolean mAnimateParentHierarchy = true;
Как это исправить?
Я предлагаю вам вообще отказаться от LayoutTransitions
(android:animateLayoutChanges="false"
) и перейти к TransitionManager
.
Мы воспользуемся удобным методом TransitionManager#beginDelayedTransition
:
beginDelayedTransition
void beginDelayedTransition (ViewGroup sceneRoot,
Переходный переход)
Удобный метод для анимации новой сцены, определяемый всеми изменениями в данном корне сцены между вызовом этого метода и следующим кадром рендеринга. Вызов этого метода приводит к тому, что TransitionManager захватывает текущие значения в корне сцены, а затем отправляет запрос на выполнение перехода в следующем кадре. В это время новые значения в корне сцены будут записаны, а изменения будут анимированы. Нет необходимости создавать сцену; это подразумевается изменениями, которые происходят между вызовом этого метода и следующим кадром, когда начинается переход.
Вот мой код для удаления и добавления вкладок. Обязательно установите animateLayoutChanges="false"
.
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mTabsAdded) {
// Get rid of the indicator due to an on-screen artifact.
tabs.setSelectedTabIndicatorHeight(0);
TransitionSet set = new TransitionSet()
.addTransition(new Fade(OUT))
.addTransition(new ChangeBounds());
TransitionManager.beginDelayedTransition(layout, set);
mAppBar.removeView(tabs);
} else {
// Add tab indicator back in.
int indicatorHeight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 2,
getResources().getDisplayMetrics());
tabs.setSelectedTabIndicatorHeight(indicatorHeight);
TransitionSet set = new TransitionSet()
.addTransition(new Fade(IN))
.addTransition(new ChangeBounds());
TransitionManager.beginDelayedTransition(layout, set);
mAppBar.addView(tabs);
}
mTabsAdded = !mTabsAdded;
}
});