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

Что выберешь явную анимацию или неявную анимацию?

1.8 Middle🔥 151 комментариев
#Анимации

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Явная vs Неявная анимация в Flutter

Это не просто технический вопрос — это вопрос о философии разработки. Оба подхода имеют своё место, и выбор зависит от контекста.

Неявная анимация (Implicit Animation)

Использование встроенных виджетов как AnimatedContainer, AnimatedOpacity, AnimatedPositioned:

class AnimatedButtonExample extends StatefulWidget {
  @override
  State<AnimatedButtonExample> createState() => _AnimatedButtonExampleState();
}

class _AnimatedButtonExampleState extends State<AnimatedButtonExample> {
  bool isExpanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() => isExpanded = !isExpanded),
      child: AnimatedContainer(
        duration: Duration(milliseconds: 300),
        curve: Curves.easeInOutCubic,
        width: isExpanded ? 200 : 100,
        height: 50,
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Center(
          child: Text(isExpanded ? 'Expanded' : 'Tap'),
        ),
      ),
    );
  }
}

Преимущества:

  • ✅ Просто и интуитивно — просто меняешь состояние, анимация срабатывает сама
  • ✅ Меньше кода — нет необходимости управлять AnimationController
  • ✅ Быстро прототипировать — идеально для simple UI changes
  • ✅ Performance — Flutter оптимизирует эти виджеты

Недостатки:

  • ❌ Ограниченный контроль — нельзя pause/resume анимацию
  • ❌ Нельзя связать несколько анимаций — если нужна композиция
  • ❌ Сложно с listener — трудно react на промежуточные значения

Явная анимация (Explicit Animation)

Использование AnimationController с полным контролем:

class ExplicitAnimationExample extends StatefulWidget {
  @override
  State<ExplicitAnimationExample> createState() => _ExplicitAnimationExampleState();
}

class _ExplicitAnimationExampleState extends State<ExplicitAnimationExample>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _sizeAnimation;
  late Animation<Color> _colorAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 500),
      vsync: this,
    );

    _sizeAnimation = Tween<double>(begin: 50, end: 200).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
    );

    _colorAnimation = ColorTween(
      begin: Colors.blue,
      end: Colors.red,
    ).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _sizeAnimation,
      builder: (context, child) {
        return GestureDetector(
          onTap: () {
            if (_controller.isCompleted) {
              _controller.reverse();
            } else {
              _controller.forward();
            }
          },
          child: Container(
            width: _sizeAnimation.value,
            height: _sizeAnimation.value,
            decoration: BoxDecoration(
              color: _colorAnimation.value,
              borderRadius: BorderRadius.circular(8),
            ),
          ),
        );
      },
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

Преимущества:

  • ✅ Полный контроль — forward, reverse, repeat, stop
  • ✅ Слушатели — addListener, addStatusListener для события
  • ✅ Композиция — можно связать несколько анимаций через Interval
  • ✅ Физические свойства — velocity, fling-animations
  • ✅ Complex interactions — реагировать на жесты и события

Недостатки:

  • ❌ Больше кода — требует управления жизненным циклом
  • ❌ Сложнее — нужно понимание AnimationController, vsync
  • ❌ Risk забыть dispose — утечка ресурсов

Мой выбор и рекомендация

Я выбираю явную анимацию (explicit) по нескольким причинам:

1. Контроль и предсказуемость В production приложениях часто нужна сложная логика: pause во время network запроса, изменение скорости анимации на основе действий пользователя, синхронизация с другими events.

2. Масштабируемость Когда проект растёт, простая AnimatedContainer может стать узким местом. Лучше сразу использовать явный подход.

3. Performance monitoring С explicit animation легче профилировать и отлаживать: как долго идёт анимация, когда она запускается, почему лагает.

4. Тестирование

test('animation completes', () async {
  final controller = AnimationController(
    duration: Duration(milliseconds: 100),
    vsync: tester,
  );

  controller.forward();
  await tester.pumpAndSettle();

  expect(controller.status, AnimationStatus.completed);
});

Гибридный подход

Для меня оптимально:

  • Простые UI transitions (fade, scale) → implicit AnimatedXxx
  • Сложная логика, gestures → explicit AnimationController
  • Очень сложные сценарии → Riverpod/GetX с явными контроллерами

Заключение

Неявная анимация идеальна для быстрого прототипирования, но явная анимация — это инвестиция в качество и поддерживаемость кода. За 10+ лет я вижу, что профессиональные приложения всё чаще требуют явного контроля, поэтому этот скилл критичен.