0Pricing
Android Academy · Урок

Анимации и переходы

Анимируйте представления с помощью ViewPropertyAnimator, ObjectAnimator и AnimatorSet. Добавляйте переходы между фрагментами, анимации общих элементов и физику пружины.

«Анимации и переходы» — бесплатный урок Android Academy на CoddyKit. Это урок 4 из 5. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 5 уроков всего.

Зачем нужны анимации

Анимации делают приложения живыми и отзывчивыми. Они:

  • Дают визуальную обратную связь на действия пользователя
  • Показывают взаимосвязь экранов
  • Делают изменения данных менее резкими
  • Помогают пользователям понять, что изменилось и почему

Главное правило: анимации должны помогать интерфейсу, а не отвлекать от него. Ограничивайте их длительность 300 мс.

ViewPropertyAnimator — быстрые анимации

Самый простой способ анимировать представление. Объединяйте вызовы в цепочку и вызывайте start():

// Fade a view out:
binding.tvMessage
    .animate()
    .alpha(0f)
    .setDuration(300)
    .withEndAction { binding.tvMessage.visibility = View.GONE }
    .start()

// Slide in from bottom:
binding.cardView.translationY = 200f
binding.cardView.alpha = 0f
binding.cardView
    .animate()
    .translationY(0f)
    .alpha(1f)
    .setDuration(250)
    .setInterpolator(DecelerateInterpolator())
    .start()

ObjectAnimator

ObjectAnimator анимирует любое свойство любого объекта по имени. Он гибче, чем ViewPropertyAnimator:

// Rotate an image:
val rotateAnimator = ObjectAnimator.ofFloat(
    binding.ivLogo,
    "rotation",
    0f, 360f
).apply {
    duration = 600
    repeatCount = ObjectAnimator.INFINITE
    interpolator = LinearInterpolator()
    start()
}

// Stop it:
rotateAnimator.cancel()

AnimatorSet — последовательно и параллельно

AnimatorSet управляет несколькими аниматорами, запуская их одновременно или один за другим:

val fadeIn  = ObjectAnimator.ofFloat(binding.card, "alpha", 0f, 1f).setDuration(300)
val scaleX  = ObjectAnimator.ofFloat(binding.card, "scaleX", 0.8f, 1f).setDuration(300)
val scaleY  = ObjectAnimator.ofFloat(binding.card, "scaleY", 0.8f, 1f).setDuration(300)
val slideUp = ObjectAnimator.ofFloat(binding.card, "translationY", 100f, 0f).setDuration(300)

AnimatorSet().apply {
    // Run fadeIn + scaleX + scaleY together, then slideUp
    play(fadeIn).with(scaleX).with(scaleY)
    play(slideUp).after(fadeIn)
    interpolator = DecelerateInterpolator()
    start()
}

Интерполяторы

Интерполяторы управляют скоростью изменения анимации. Распространённые варианты:

  • LinearInterpolator — постоянная скорость
  • AccelerateInterpolator — начинается медленно, затем ускоряется (выход)
  • DecelerateInterpolator — начинается быстро, затем замедляется (появление)
  • AccelerateDecelerateInterpolator — медленно → быстро → медленно (по умолчанию)
  • OvershootInterpolator — проходит за целевую точку и возвращается обратно
  • BounceInterpolator — подпрыгивает в конце

TransitionManager — изменения макета

Автоматически анимируйте изменения макета, вызвав TransitionManager.beginDelayedTransition() перед изменением видимости или свойств макета:

binding.btnToggle.setOnClickListener {
    // Tell the framework to animate the next layout change
    TransitionManager.beginDelayedTransition(
        binding.root,
        ChangeBounds().apply { duration = 300 }
    )

    // Now change visibility/size — Android animates the difference automatically
    binding.expandedSection.visibility =
        if (binding.expandedSection.isVisible) View.GONE else View.VISIBLE
}

Переходы между фрагментами

Добавляйте анимации появления и исчезновения в транзакции фрагментов:

supportFragmentManager.beginTransaction()
    .setCustomAnimations(
        R.anim.slide_in_right,   // enterAnim
        R.anim.slide_out_left,   // exitAnim
        R.anim.slide_in_left,    // popEnterAnim
        R.anim.slide_out_right   // popExitAnim
    )
    .replace(R.id.container, DetailFragment())
    .addToBackStack(null)
    .commit()

// Or use MaterialSharedAxis for a modern, Material Motion feel:
val forward = MaterialSharedAxis(MaterialSharedAxis.X, true)
exitTransition = forward
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)

Переходы общих элементов

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

// In ListFragment:
binding.ivThumbnail.transitionName = "hero_image_${item.id}"

val extras = FragmentNavigatorExtras(
    binding.ivThumbnail to "hero_image_${item.id}"
)
findNavController().navigate(R.id.action_list_to_detail, null, null, extras)

// In DetailFragment:
sharedElementEnterTransition = TransitionInflater
    .from(requireContext())
    .inflateTransition(android.R.transition.move)

// ImageView in detail layout must have the same transitionName

Пружинная анимация

Пружинные анимации выглядят естественнее линейных анимаций и анимаций с замедлением, потому что имитируют физику пружины:

implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'

// Spring animation on a button press:
val spring = SpringAnimation(binding.fabAdd, DynamicAnimation.SCALE_X, 1f).apply {
    spring = SpringForce(1f).apply {
        stiffness = SpringForce.STIFFNESS_MEDIUM
        dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
    }
}

binding.fabAdd.setOnClickListener {
    binding.fabAdd.scaleX = 0.8f
    spring.start()
}

Lottie — сложные анимации

Lottie воспроизводит анимации After Effects, экспортированные в формате JSON. Идеально подходит для индикаторов загрузки, приветственных экранов и пустых состояний:

// app/build.gradle:
// implementation 'com.airbnb.android:lottie:6.4.0'

<!-- In layout XML -->
<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/lottieView"
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:lottie_rawRes="@raw/loading_animation"
    app:lottie_autoPlay="true"
    app:lottie_loop="true" />

// Control in code:
binding.lottieView.playAnimation()
binding.lottieView.pauseAnimation()

Рекомендации по анимации

Рекомендации для плавных и доступных анимаций:

  • Для большинства анимаций интерфейса используйте длительность 150–300 мс
  • Всегда учитывайте AnimatorUtils.areAnimatorsEnabled() или Settings.System.ANIMATOR_DURATION_SCALE
  • Пользователи с вестибулярными расстройствами могут отключать анимации — проверяйте настройку доступности Reduce Motion
  • Не анимируйте то, что в этом не нуждается, — чем меньше, тем лучше
  • Проверяйте работу на недорогих устройствах (анимации могут вызывать пропуски кадров)

Быстрая проверка

Какой интерполятор лучше всего подходит для появления элемента на экране с ощущением замедления и плавной остановки?

Повторение: анимации и переходы

Оживите приложение с помощью плавных анимаций:

  • view.animate() — быстрая настройка прозрачности, перемещения, масштаба и поворота
  • ObjectAnimator — анимация любого свойства с точным управлением
  • AnimatorSet — координация нескольких аниматоров (с помощью with/after)
  • TransitionManager.beginDelayedTransition() — автоматическая анимация изменений макета
  • Переходы общих элементов — плавная непрерывность между экранами
  • Lottie — сложные анимации JSON из After Effects

Далее: нижняя навигация и вкладки для приложений с несколькими разделами.

Часто задаваемые вопросы

Урок «Анимации и переходы» бесплатный?

Да — полный текст урока «Анимации и переходы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 5 уроков всего.

Чему я научусь в уроке «Анимации и переходы»?

Анимируйте представления с помощью ViewPropertyAnimator, ObjectAnimator и AnimatorSet. Добавляйте переходы между фрагментами, анимации общих элементов и физику пружины. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 5.

Сколько времени занимает урок «Анимации и переходы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы Material Design
  2. Темы и стили
  3. Пользовательские представления
  4. Анимации и переходы
  5. Нижняя навигация и вкладки
← Назад к Android Academy