Анимации и переходы
Анимируйте представления с помощью 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 — локальная установка не требуется.
Все уроки этого курса
- Основы Material Design
- Темы и стили
- Пользовательские представления
- Анимации и переходы
- Нижняя навигация и вкладки