TL; DR: Я ищу полный рабочий образец того, что я буду называть сценарием «трехфрагментной анимации Gmail». В частности, мы хотим начать с двух фрагментов, например:
После некоторого события пользовательского интерфейса (например, касания чего-либо во фрагменте B) мы хотим:
- Фрагмент A, чтобы соскользнуть с экрана влево
- Фрагмент B переместится к левому краю экрана и уменьшится, чтобы занять место, освобожденное фрагментом A
- Фрагмент C, чтобы проскользнуть из правой части экрана и занять место, освобожденное фрагментом B
И при нажатии кнопки BACK мы хотим, чтобы этот набор операций был отменен.
Я видел множество частичных реализаций; Я рассмотрю четыре из них ниже. Помимо того, что они неполные, у всех есть свои проблемы.
@Reto Meier предоставил этот популярный ответ на тот же основной вопрос, указав, что вы будете использовать setCustomAnimations()
с расширением FragmentTransaction
. Для сценария с двумя фрагментами (например, вы сначала видите только фрагмент A и хотите заменить его новым фрагментом B с использованием анимированных эффектов) я полностью согласен. Тем не мение:
- Поскольку вы можете указать только одну «входящую» и одну «выходную» анимацию, я не понимаю, как вы будете обрабатывать все различные анимации, необходимые для сценария с тремя фрагментами.
- В
<objectAnimator>
его образце кода используются жестко привязанные позиции в пикселях, и это может показаться непрактичным с учетом различных размеров экрана, ноsetCustomAnimations()
требует ресурсов анимации, что исключает возможность определения этих вещей в Java. - Я в недоумении, как объект аниматоры для масштаба галстука в таких вещах , как
android:layout_weight
вLinearLayout
выделение пространства на основе процента - Я не понимаю, как фрагмент C обрабатывается с самого начала (
GONE
?android:layout_weight
Из0
? Предварительно анимированных до шкалы 0? Что-то еще?)
@Roman Nurik указывает, что вы можете анимировать любое свойство , включая те, которые вы определяете сами. Это может помочь решить проблему жестко зашитых позиций за счет изобретения собственного подкласса настраиваемого менеджера компоновки. Некоторым это помогает, но остальное решение Reto меня все еще сбивает с толку.
Автор этой записи pastebin показывает некоторый дразнящий псевдокод, в основном говоря, что все три фрагмента изначально будут находиться в контейнере, а фрагмент C будет скрыт с самого начала посредством hide()
операции транзакции. Затем мы show()
C и hide()
A, когда происходит событие пользовательского интерфейса. Однако я не понимаю, как это связано с тем, что B меняет размер. Он также основан на том факте, что вы, по-видимому, можете добавить несколько фрагментов в один и тот же контейнер, и я не уверен, является ли это надежным поведением в долгосрочной перспективе (не говоря уже о том, что оно должно сломаться findFragmentById()
, хотя я могу с этим жить).
Автор этого сообщения в блоге указывает, что Gmail вообще не использует setCustomAnimations()
, а вместо этого напрямую использует аниматоры объектов («вы просто меняете левое поле корневого представления + меняете ширину правого представления»). Тем не менее, это все еще двухфрагментное решение AFAICT, и реализация снова показала жесткие размеры в пикселях.
Я продолжу заниматься этим, так что я, возможно, когда-нибудь сам отвечу на этот вопрос, но я действительно надеюсь, что кто-то разработал решение из трех фрагментов для этого сценария анимации и может опубликовать код (или ссылку на него). Анимация в Android заставляет меня выдергивать волосы, и те из вас, кто видел меня, знают, что это в значительной степени бесплодное занятие.