Ответ
Flutter предоставляет мощную и гибкую систему анимаций, которая делится на два основных типа: неявные (implicit) и явные (explicit). Все анимации работают на 60/120 FPS благодаря движку Skia.
1. Неявные анимации (Implicit Animations)
Самый простой способ. Используются специальные виджеты (с префиксом Animated...), которые автоматически анимируют изменения своих свойств.
bool _selected = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => setState(() => _selected = !_selected),
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut, // Кривая для естественного движения.
width: _selected ? 200 : 100,
height: _selected ? 200 : 100,
color: _selected ? Colors.blue : Colors.grey,
child: Center(child: Text('Tap me')),
),
);
}
Другие примеры: AnimatedOpacity, AnimatedPadding, AnimatedAlign.
2. Явные анимации (Explicit Animations)
Дают полный контроль над анимацией через AnimationController. Используются для сложных, составных или повторяющихся анимаций.
class _RotationAnimation extends StatefulWidget {
@override
_RotationAnimationState createState() => _RotationAnimationState();
}
class _RotationAnimationState extends State<_RotationAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
// Контроллер управляет временем анимации (vsync синхронизирует с частотой кадров).
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
);
// Tween определяет диапазон значений анимации.
_animation = Tween<double>(begin: 0, end: 2 * pi).animate(_controller);
_controller.repeat(); // Запускаем анимацию на повтор.
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.rotate(
angle: _animation.value,
child: FlutterLogo(size: 100),
);
},
);
}
@override
void dispose() {
_controller.dispose(); // Важно: всегда освобождаем контроллер.
super.dispose();
}
}
3. Анимации на основе физики (Physics-based)
Имитируют реальное движение (пружины, гравитация) через SpringSimulation, GravitySimulation.
4. Hero-анимации
Для плавного перехода виджета между экранами (навигации).
// На первом экране
Hero(
tag: 'avatar', // Уникальный тег.
child: CircleAvatar(backgroundImage: NetworkImage(url)),
)
// На втором экране используем виджет с тем же тегом.
Hero(
tag: 'avatar',
child: Image.network(url, fit: BoxFit.cover),
)
5. Интеграция с Rive/Lottie
Для сложных векторных анимаций, созданных дизайнерами, используется пакет rive или lottie. Это позволяет загружать готовые анимации из Figma или After Effects.
Ключевой принцип: В Flutter анимация — это просто интерполяция значений (числа, цвета и т.д.) во времени, управляемая Animation объектами. Виджеты перерисовываются на каждом кадре с новым значением, создавая иллюзию движения.