Умирающие дети с героями просмотров в переходе общего элемента

Мне любопытно, как андроид обрабатывает дочерние элементы героя в переходе общего элемента, который можно увидеть в Google Keep:

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

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

Это создает эффект довольно jarring, если есть какие-либо различия в содержании двух представлений героев - например, текстовое представление, где линии обертываются по-другому или разные представления для детей.

Между тем, в Google Keep переход на общий элемент, кажется, постепенно размывает представления контента вперед и назад, поэтому этот эффект jarring значительно менее заметен. Следовательно, различия в вещах, таких как заполнение или обтекание строк, гораздо менее проблематичны.

Какой лучший способ для меня реализовать это в моем собственном приложении?

Вот пример:

введите описание изображения здесь

Ответ 1

Мой ответ длинный. И он предоставляет только общую структуру для воссоздания того, что я видел в вашем анимированном изображении, поэтому вам нужно будет потратить некоторое время на то, чтобы настроить все, чтобы он стал идеальным.

Код можно увидеть здесь: https://gist.github.com/zizibaloob/e107fe80afa6873301bf234702d4b2b9

tl; dr: "Общий элемент" - это только зеленая карта/фон, поэтому вы создаете переход с помощью этих. Поместите серый фон за зеленым фоном на вторую активность, чтобы зеленый мог что-то рисовать сверху, пока он растет. Оберните весь свой контент в родительском представлении и анимируйте его alpha, чтобы затухать в/из.

Полный ответ

На вашем изображении "общий элемент" представляется зеленой карточкой на первом экране/зеленом фоне второго экрана. Кроме того, мы добавляем два дополнительных требования:

  • Серый фон первого действия должен быть видимым во время перехода
  • Содержимое карты исчезает, а затем исчезает во время/после перехода.

Пропустите каждый файл и расскажите о том, какие варианты я сделал для достижения желаемых результатов...

activity_main.xml

Это действительно просто. Я только что создал иерархию представлений, которая смутно напоминала ту, что была на вашем изображении. Пустой View наверху является заполнителем для Toolbar, а Space в нижней части карты - просто чтобы сделать его немного больше.

activity_other.xml

Соответствующей частью этого макета является тройной стек "родительских" представлений. Каждая из них служит цели:

  • Верхний уровень FrameLayout обеспечивает серый фон для карты, чтобы "расти" поверх
  • Среднее FrameLayout обеспечивает зеленый фон, который будет использоваться совместно между действиями.
  • Внутренний LinearLayout обертывает все, что мы хотим угасить в/из, и будет анимироваться с помощью кода в классе Activity

MainActivity.java

Еще один простой класс. Все это Activity делает карту кликабельной и настраивает переход.

OtherActivity.java

Большая часть магии происходит здесь. Внутри onCreate() материал Toolbar является стандартным, поэтому мы можем пропустить это. Код внутри оператора if - это то, что устанавливает анимацию затухания (завернутый в if, поэтому он только исчезает при первом запуске). Я также переопределил onBackPressed(), чтобы отменить анимацию затухания и вызвать переход возврата.

shared_element_transition.xml

Все остальное волшебство находится в этом файле. Элемент <targets> исключает статус и навигационные панели, которые гарантируют, что они не будут мигать во время перехода. Различные теги <changeFoo> - это фактическая анимация перехода, которая воспроизводится.

styles.xml

Единственная причина, по которой я включил это в Gist, - это стиль TransitionTheme. Это применяется к OtherActivity в манифесте, и это то, что устанавливает наш пользовательский переход (от shared_element_transition.xml).

введите описание изображения здесь