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
of0
? до анимированный до шкалы 0? что-то еще?)
@Roman Nurik указывает, что можно анимировать любое свойство, включая те, которые вы сами определяете. Это может помочь решить проблему с жесткими проводными позициями за счет разработки собственного подкласса менеджера компоновки. Это помогает некоторым, но я все еще озадачен остальным решением Reto.
Автор эта запись в pastebin показывает некоторый дразнящий псевдокод, в основном говорящий, что все три фрагмента будут сначала находиться в контейнере, а фрагмент C скрыт в начале с помощью операции транзакции hide()
. Затем мы получаем show()
C и hide()
A, когда происходит событие UI. Однако я не вижу, как это влияет на то, что B меняет размер. Он также полагается на то, что вы, видимо, можете добавить несколько фрагментов в один и тот же контейнер, и я не уверен, является ли это надежным поведением в долгосрочной перспективе (не говоря уже о том, что он должен разорвать findFragmentById()
, хотя я могу жить с что).
Автор этот пост в блоге указывает, что Gmail вообще не использует setCustomAnimations()
, но вместо этого напрямую использует объектные аниматоры ( "вы просто изменить левое поле корневого представления + изменить ширину правильного вида" ). Тем не менее, это все еще двухфакторное решение AFAICT, и реализация снова показывает размеры жестких проводов в пикселях.
Я продолжу подключаться к этому, так что я могу сам ответить на это сам, но я действительно надеюсь, что кто-то разработал решение из трех фрагментов для этого сценария анимации и может опубликовать код (или ссылку на него)). Анимации в Android заставляют меня хотеть вытащить мои волосы, и те из вас, кто видел меня, знают, что это в значительной степени бесплодное усилие.