← Назад к вопросам

Делал ли анимации на View

1.3 Junior🔥 162 комментариев
#UI и вёрстка#Опыт и софт-скиллы

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Да, конечно. Делал и довольно много. Работа с анимациями на View — это фундаментальный навык для Android-разработчика, хотя в современной разработке все больше смещается в сторону Compose. Весь опыт можно разделить на использование традиционных инструментов из Android SDK и на более гибкие, низкоуровневые подходы.

Вот основные подходы и технологии, которые я применял:

### 1. ViewPropertyAnimator (API 12+)

Самый простой и оптимизированный способ анимировать базовые свойства View (alpha, translationX/Y, rotation, scaleX/Y). Он автоматически использует аппаратное ускорение.

myView.animate()
    .alpha(0.5f)
    .translationX(100f)
    .scaleX(1.5f)
    .setDuration(300)
    .setInterpolator(AccelerateDecelerateInterpolator())
    .withEndAction { /* Действие после завершения */ }
    .start()

### 2. ObjectAnimator и ValueAnimator (API 11+)

Часть Property Animation API. ObjectAnimator изменяет конкретное свойство объекта, а ValueAnimator просто генерирует значения, которые можно использовать для любой логики.

Пример ObjectAnimator (анимация цвета фона, используя ArgbEvaluator):

val animator = ObjectAnimator.ofInt(
    myView,
    "backgroundColor",
    Color.RED,
    Color.BLUE
).apply {
    duration = 500
    setEvaluator(ArgbEvaluator())
    repeatCount = 1
    repeatMode = ObjectAnimator.REVERSE
}
animator.start()

Пример ValueAnimator для кастомной анимации пути:

val path = Path().apply {
    moveTo(0f, 0f)
    quadTo(100f, 200f, 300f, 0f)
}
val pathAnimator = ObjectAnimator.ofFloat(myView, "translationX", "translationY", path).apply {
    duration = 1000
}

### 3. AnimationDrawable для покадровой анимации

Использовал для простых последовательностей изображений (например, индикатор загрузки).

<!-- res/drawable/loading_animation.xml -->
<animation-list android:oneshot="false">
    <item android:drawable="@drawable/frame1" android:duration="100" />
    <item android:drawable="@drawable/frame2" android:duration="100" />
</animation-list>
val animation = imageView.drawable as AnimationDrawable
animation.start()

### 4. Ручное управление анимацией через onDraw() и ValueAnimator

Для сложных, нестандартных анимаций, где нужно анимировать не стандартные свойства, а какие-то внутренние параметры отрисовки. Здесь ValueAnimator обновляет кастомное свойство, и мы вызываем invalidate() для перерисовки.

class CustomAnimatedView(context: Context) : View(context) {
    private var animatedRadius = 0f
    private val animator = ValueAnimator.ofFloat(0f, 100f).apply {
        duration = 1000
        addUpdateListener {
            animatedRadius = it.animatedValue as Float
            invalidate() // Запускает перерисовку (вызов onDraw)
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        paint.color = Color.BLUE
        canvas.drawCircle(width / 2f, height / 2f, animatedRadius, paint)
    }

    fun startAnimation() {
        animator.start()
    }
}

### Ключевые аспекты и проблемы, с которыми сталкивался:

  • Производительность: Всегда стремился использовать аппаратное ускорение (ViewPropertyAnimator, ObjectAnimator с правильными свойствами). Для анимации, запущенной в onDraw(), критически важно минимизировать аллокации объектов (например, переиспользовать Paint, Path).
  • Прерывания и состояние: Обработка корректной отмены анимаций при уходе Activity/Fragment в onPause() или onDestroy() для предотвращения утечек памяти.
  • Совместимость и обратная связь: Использовал ViewCompat или библиотеки поддержки (Support Library) для переноса некоторых возможностей на старые версии API.
  • Интерполяция (Interpolator): Правильный выбор Interpolator (AccelerateDecelerateInterpolator, OvershootInterpolator, BounceInterpolator) — это 80% успеха для создания "живой", естественной анимации.
  • Совместные анимации: Использовал AnimatorSet для запуска последовательных или параллельных анимаций.
    AnimatorSet().apply {
        play(animatorX).with(animatorY).before(animatorFadeOut)
        start()
    }
    

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

Опыт с анимацией на View научил меня понимать, как анимация работает "под капотом" системы Android, как управлять временем, плавностью и как интегрировать визуальную динамику в логику приложения, не блокируя главный поток. Этот базис невероятно полезен даже при переходе на Compose.

Делал ли анимации на View | PrepBro