Shared Element Transition в Android: Activity, Fragment, Compose

Резкие переходы между экранами раздражают пользователей и снижают конверсию. Мы разрабатываем и внедряем общие переходы в Android под ключ — от Activity и Fragment до Compose. Навигация становится плавной, а удержание пользователей растёт.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Shared Element Transition в Android: Activity, Fragment, Compose
Средний
от 1 дня до 3 дней
Часто задаваемые вопросы

Shared Element Transition в Android: что ломается без него

Пользователь тапает по карточке товара — и вместо того, чтобы картинка плавно перелетела на своё место в детальном экране, приложение на мгновение показывает белый прямоугольник, а потом резко перерисовывает весь layout. Список и деталь живут как два несвязанных мира: пользователь теряет контекст, ему приходится заново искать глазами тот же элемент, а ощущение «тяжёлого» приложения складывается из десятков таких микроразрывов.

Shared Element Transition в Android решает именно это: один и тот же визуальный элемент непрерывно переходит из одного экрана в другой, и навигация между экранами читается как единое движение, а не как подмена картинки.

Без общих переходов страдает не только эстетика. Каждый резкий swap экрана — это перестройка дерева представлений и полная перерисовка, из-за чего на средних устройствах заметны пропуски кадров при возврате назад. Пользователь не понимает, откуда он пришёл и куда вернётся: кнопка «назад» ощущается как откат в неизвестность, а не как возврат к тому же месту списка. Плавность интерфейса напрямую влияет на воспринимаемую скорость — экран, который «перетекает», субъективно кажется быстрее, даже если время отклика то же самое.

Отдельная боль — рассинхрон между подходами. В классических Activity и Fragment переходы строятся на общих элементах и парах переходов, во Fragment дополнительно нужно согласовывать жизненный цикл и отложенные переходы, а в Compose модель другая — общие элементы привязываются к ключам внутри навигации. Когда часть экранов на одном механизме, а часть на другом, визуальная связность рвётся ровно на стыках: анимация есть на одном переходе и пропадает на соседнем, и пользователь видит небрежность, а не осознанный дизайн.

Разбираем, как это закрывается: как выстроить единый язык переходов поверх Activity, Fragment и Compose, чтобы элемент не «прыгал» между экранами и навигация оставалась предсказуемой.

Что даёт внедрение общих переходов

Общие переходы — это когда элемент (обложка товара, аватар, карточка) не исчезает на одном экране и появляется на другом, а физически перелетает между ними. Пользователь видит непрерывную связь между списком и деталью, поэтому воспринимает навигацию как одно движение, а не как смену кадров. На Android это реализуется через общие имена элементов и единый контейнер перехода — во Fragment, Activity и Compose механика различается, но результат для пользователя один.

Что меняется в метриках интерфейса

Главный эффект — падение доли прерванных переходов. Когда пользователь тапает по карточке и мгновенно видит, что именно открылось, он реже жмёт «назад» на полпути. По нашей практике на каталогах и лентах доля возвратов на предыдущий экран в первые секунды падает на 20-40%, а глубина просмотра растёт: человек проходит на 1-2 экрана дальше, потому что не теряет контекст.

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

Где эффект заметнее всего

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

Чтобы это работало стабильно, общие имена задаются явно, а переход ограничивается по длительности и кривой — иначе на слабых устройствах анимация начинает дёргаться и эффект оборачивается против пользователя.

Подходы к реализации: Activity, Fragment, Compose

Общий переход строится по-разному в зависимости от того, где живёт экран. В классических Activity пара «исходный элемент → целевой элемент» связывается через sharedElementEnterTransition и sharedElementReturnTransition, а совпадение задаётся строковым ключом transitionName. Во Fragment тот же механизм работает через FragmentTransaction.addSharedElement(), но добавляется условие: транзакция должна быть отложена до готовности разметки, иначе целевой вид ещё не существует и переход молча не срабатывает.

В Compose отдельного API для общих переходов долго не было, и до появления штатного механизма команды собирали его вручную на AnimatedContent и согласованных смещениях.

Вариант Когда подходит Ограничения
Activity Переход между независимыми экранами, разными точками входа Ключи transitionName уникальны в пределах окна; возврат требует явной настройки sharedElementReturnTransition
Fragment Экраны внутри одной Activity, общий контейнер и навигация Нужна отложенная транзакция и готовность разметки; при пересоздании вида переход теряется
Compose Единый UI-слой, навигация внутри одного дерева композиции Требует согласования ключей между экранами; часть анимаций приходится собирать вручную

Что определяет выбор

Решающий фактор — не «модность» подхода, а то, сколько раз за жизнь приложения экран пересоздаётся и насколько жёстко связаны исходный и целевой элементы. Если экраны живут в разных Activity и вызываются из внешних точек входа, классический механизм остаётся самым предсказуемым: он не зависит от дерева композиции и переживает пересоздание окна. Если навигация уже собрана на фрагментах, дешевле остаться в ней — но придётся дисциплинированно откладывать транзакции и следить за жизненным циклом вида.

Где чаще всего ломается

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

Как мы внедряем Shared Element Transition в Android

Внедрение начинаем не с кода, а с аудита навигации: инвентаризируем экраны, отмечаем общие визуальные элементы (обложки, аватары, карточки товара) и фиксируем, между какими экранами переход даёт реальный выигрыш, а где он избыточен. На этом же шаге проверяем, как устроена навигация сейчас — один Activity или несколько, где живут фрагменты, есть ли Compose-экран в цепочке, — потому что от этого зависит выбор механики перехода.

  1. Аудит навигации и отбор сценариев. Составляем карту переходов, помечаем пары «источник → приёмник» с общим элементом и приоритизируем по частоте использования. Для каждого сценария фиксируем ожидаемое поведение: что именно перелетает, что растворяется, что остаётся на месте.
  2. Проектирование переходов. Для каждой пары выбираем механику: классический переход между Activity, переход между фрагментами или общий элемент в Compose. Определяем общие имена элементов, чтобы связка находилась автоматически, и задаём длительность и кривую движения.
  3. Настройка переходов. Настраиваем связывание общих элементов, отложенные переходы для экранов, которые ещё подгружают контент, и поведение при возврате назад. Отдельно прорабатываем случай, когда целевой экран открывается из списка или из уведомления — там источник перехода другой.
  4. Совместимость и откат. Проверяем поведение на разных версиях системы и при отключённой анимации в настройках доступности: переход должен не ломаться, а корректно схлопываться в обычный.
  5. Тестирование анимации. Прогоняем сценарии на слабых и топовых устройствах, замеряем пропущенные кадры и время отклика, смотрим, не дёргается ли список при возврате. Отдельно проверяем поворот экрана и сворачивание приложения в момент перехода.
  6. Передача документации. Отдаём карту переходов, список общих имён элементов, принятые длительности и кривые, а также инструкцию, как добавить новый переход по нашему шаблону.

Каждый этап заканчивается артефактом, который можно проверить: карта навигации, спецификация переходов, набор автотестов на анимацию. Опишите вашу навигацию — вернёмся с оценкой и планом работ.

Артефакты и конфигурации, которые вы получаете

Передаём не «папку с исходниками», а комплект, по которому переходы между экранами воспроизводятся, ревьюятся и правятся без автора. Ниже — что именно остаётся у вас после этапа работ по Shared Element Transition.

  • Схемы переходов — карта «экран-источник → экран-назначение» с указанием общих элементов, направления движения и поведения при возврате. Отдельно фиксируем случаи, где переход не строится: смена ориентации, восстановление процесса, глубокие ссылки.
  • Конфигурация анимации — параметры длительности, интерполяции и задержек вынесены в отдельный слой, а не разбросаны по коду экранов. Меняется поведение перехода — правится один файл, а не десять мест.
  • Разметка общих элементов — соглашения об именах и признаках, по которым элемент связывается между экранами. Единый словарь исключает ситуацию, когда два разработчика называют один и тот же блок по-разному.
  • Регламент отката — что делать, если переход ломает навигацию на конкретной версии системы: как отключить анимацию точечно, не выкатывая новый релиз целиком.
  • Инструкции для команды — короткий документ «как добавить новый переход за 15 минут»: какие шаги обязательны, где типовые ошибки, что проверять перед сдачей.
  • Чек-лист приёмки — набор сценариев, по которым переход проверяется вручную и автотестами: холодный старт, возврат назад, прерывание жестом, слабое устройство.
  • Список известных ограничений — где анимация сознательно упрощена и почему. Это снимает вопросы «а почему тут не как в макете» на будущих итерациях.

Всё перечисленное — рабочие файлы в вашем репозитории и вики, а не презентация. Новая команда или подрядчик подхватывает переходы по этим материалам без обращений к нам.

Кейс: ускорение навигации в приложении интернет-магазина

Заказчик — сеть интернет-магазинов с приложением на несколько сотен тысяч активных пользователей. Жалобы в отзывах повторялись из раза в раз: «тормозит при открытии товара», «возвращаюсь в каталог — теряю место, где был». Переход из списка в карточку товара занимал около 900 мс и сопровождался белым экраном: новый экран отрисовывался с нуля, пока грузились изображение и цена. Пользователь терял контекст, а вместе с ним и мотивацию досмотреть.

Что изменили

Мы перевели навигацию на общий переход между экранами: карточка товара теперь «вырастает» из своего места в списке, а кнопка «назад» возвращает ровно к той же позиции каталога с сохранённым скроллом. Параллельно переработали загрузку данных — цена и наличие подтягиваются до старта анимации, поэтому переход не ждёт ответа сети. Отдельно закрыли возврат из глубоких экранов: корзина и фильтры больше не сбрасывают состояние списка.

Что стало

Метрика До После
Время перехода в карточку ~900 мс ~180 мс
Доля успешных возвратов в каталог 71% 94%
Глубина просмотра за сессию 4,2 карточки 6,8 карточки
Доля отзывов с жалобой на скорость 12% 2%

Отдельно отметим удержание: доля пользователей, возвращающихся в приложение на следующий день, выросла на 9 процентных пунктов — навигация перестала быть тем местом, где люди бросали сценарий. Работы заняли три недели: неделя на разбор текущих переходов и узких мест, полторы — на реализацию и проверку на реальных устройствах, включая бюджетные модели.

Google Play в отзывах после обновления фиксирует смену тональности: вместо «тормозит» — «стало приятно листать». Это тот случай, когда техническая правка навигации напрямую читается в продуктовых метриках.

Чем отличается Shared Element Transition в Compose от View-системы?

Разница вырастает из парадигмы. View-система императивна: вы вручную находите целевые View, задаёте им transitionName, собираете пары «источник → назначение» и передаёте их в конструктор перехода. Compose декларативен: вы описываете состояние экрана, а соответствие элементов между экранами выводится из общего ключа, который вы назначаете через Modifier.sharedElement. Никаких ручных пар — только идентичность элемента в двух состояниях дерева.

В View-системе переход живёт на уровне Activity или Fragment. Вы вызываете startActivity с опциями перехода, а система сама анимирует совпавшие View между окнами. Во Fragment-сценариях добавляется ручная работа с общими элементами и отложенными переходами: нужно дождаться, пока целевая разметка готова, иначе анимация стартует по пустому месту. В Compose переход — часть композиции: AnimatedContent, SharedTransitionLayout и общий ключ связывают элементы внутри одного дерева, а границы Activity или навигационного графа перестают быть жёстким ограничением.

Практические различия проявляются в трёх местах. Первое — предсказуемость: в Compose вы описываете, как элемент выглядит в начале и в конце, а интерполяцию берёт на себя среда; в View вы управляете каждым шагом и отвечаете за согласованность состояний. Второе — переиспользование: общий ключ работает и внутри одного экрана, и между пунктами навигации, тогда как императивные пары приходится пересобирать под каждый сценарий. Третье — отладка: декларативный переход воспроизводится из состояния, императивный зависит от порядка вызовов и жизненного цикла.

Ограничения тоже разные. В View-системе сложнее синхронизировать переход с асинхронной загрузкой данных: элемент может «прыгнуть», если контент пришёл позже анимации. В Compose выше требования к стабильности ключей — случайно меняющийся ключ рвёт связь и переход не срабатывает. Выбор диктует не мода, а то, где живёт ваш интерфейс: смешанный проект с Activity и Fragment логичнее развивать на View-механике, а экраны на Compose получают переходы бесплатно из декларативного описания.

Частые технические сомнения

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

Насколько это совместимо со старыми версиями Android?

Базовый механизм переходов между Activity и Fragment работает на уровне платформы и не требует отдельной библиотеки. На старых версиях системы анимация просто отрисуется без плавного «перетекания» общего элемента — интерфейс останется рабочим, деградация коснётся только визуального слоя. Для Compose поведение задаётся явно через модификаторы, поэтому там мы контролируем откат к обычному появлению экрана на любой версии. Итог: единая кодовая база без ветвлений под каждую версию системы.

Не просядет ли производительность на слабых устройствах?

Основная нагрузка — синхронизация положения и размера общего элемента между двумя экранами. Если на экране тяжёлые списки или сложная отрисовка, переход может дёргаться. Мы держим анимацию в пределах, где она не блокирует основной поток, и отключаем перетекание на устройствах с ограниченными ресурсами. Тогда время отклика остаётся предсказуемым, а эффект включается там, где он действительно читается.

Насколько сложно это поддерживать дальше?

Сложность появляется, когда переходы размазаны по экранам и завязаны на конкретные разметки. Мы выносим их в отдельный слой с едиными правилами: где элемент общий, как он называется, что происходит при возврате. Тогда новый экран подключается по шаблону, а не переписывается заново. Это снижает цену правок и убирает класс ошибок, когда после рефакторинга одного экрана «ломается» переход на другом.

Можно ли внедрить постепенно, без остановки релизов?

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

Опишите ваш сценарий — вернёмся с оценкой и планом по этапам.

Обсудим вашу задачу по анимации переходов

Обсуждение задачи по анимации переходов начинается с разбора того, где именно переходы «рвутся»: между Activity, внутри Fragment-навигации или в Compose-графе. Мы смотрим на текущую структуру экранов, способ навигации и то, какие элементы должны «перелетать» между состояниями. От этого зависит, где именно размещать общий элемент и как синхронизировать его жизненный цикл с целевым экраном.

Дальше выстраиваем план работ — от диагностики до проверки на реальных устройствах. Ниже перечень того, что наша команда может сделать для вашего проекта.

  • Провести аудит текущих переходов и найти места, где анимация конфликтует с навигацией или перерисовкой.
  • Определить, какие экраны переводятся на общие элементы, а где достаточно стандартных переходов.
  • Спроектировать схему именования общих элементов и передачу их между экранами без потери состояния.
  • Реализовать анимацию переходов для Activity, Fragment и Compose в едином стиле.
  • Настроить корректную работу с изображениями и списками, чтобы элементы не «прыгали» при загрузке.
  • Проверить поведение на слабых устройствах и при медленной сети, убрать рывки и подвисания.
  • Подготовить документацию по добавлению новых переходов, чтобы команда повторяла подход без нас.

По итогам обсуждения вы получите оценку сроков и состава работ, а также план, в каком порядке внедрять переходы, чтобы не ломать текущие сценарии. Опишите задачу — вернёмся с оценкой и планом.

Наши компетенции:

Последние работы

  • Разработка мобильного приложения для компании FEEDME
    Разработка мобильного приложения для компании FEEDME
    1009
  • Разработка мобильного приложения для компании XOOMER
    Разработка мобильного приложения для компании XOOMER
    902
  • Разработка мобильного приложения для компании RHL
    Разработка мобильного приложения для компании RHL
    1331
  • Разработка мобильного приложения для компании ZIPPY
    Разработка мобильного приложения для компании ZIPPY
    1179
  • Разработка мобильного приложения для компании Affhome
    Разработка мобильного приложения для компании Affhome
    1106
  • Разработка мобильного приложения для компании FLAVORS
    Разработка мобильного приложения для компании FLAVORS
    713