Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Явные анимации в Flutter
Явные анимации (Explicit Animations) — это анимации, которые вы полностью контролируете через AnimationController. В отличие от неявных анимаций (implicit), вы сами управляете началом, длительностью и прогрессом анимации.
Явные vs Неявные анимации
Неявные анимации — это просто:
// Неявная анимация: просто меняем свойство
AnimatedContainer(
duration: Duration(seconds: 1),
width: isExpanded ? 200 : 100,
height: isExpanded ? 200 : 100,
color: Colors.blue,
)
Явные анимации — полный контроль:
// Явная анимация: мы управляем всем
AnimationController controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this,
);
controller.forward(); // начало
controller.reverse(); // отмена
controller.stop(); // остановка
Основные компоненты
- AnimationController — управляет анимацией
- Animation — описывает значение анимации
- Tween — диапазон значений (от...до)
- Curve — кривая анимации (ускорение, замедление)
Пример 1: Простая явная анимация
class ExplicitAnimationExample extends StatefulWidget {
@override
State<ExplicitAnimationExample> createState() => _ExplicitAnimationExampleState();
}
class _ExplicitAnimationExampleState extends State<ExplicitAnimationExample>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
// Создаём controller
_controller = AnimationController(
duration: Duration(seconds: 2),
vsync: this, // требуется TickerProvider
);
// Создаём анимацию от 0 к 200
_animation = Tween<double>(begin: 0, end: 200).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _startAnimation() {
_controller.forward();
}
void _reverseAnimation() {
_controller.reverse();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// AnimatedBuilder перестраивается при изменении animation
AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Container(
width: _animation.value,
height: _animation.value,
color: Colors.blue,
);
},
),
SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _startAnimation,
child: Text('Начать'),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: _reverseAnimation,
child: Text('Отмена'),
),
],
),
],
),
),
);
}
}
Пример 2: Анимация поворота
class RotationAnimationExample extends StatefulWidget {
@override
State<RotationAnimationExample> createState() => _RotationAnimationExampleState();
}
class _RotationAnimationExampleState extends State<RotationAnimationExample>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 2),
vsync: this,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// RotationTransition использует встроенную поддержку поворота
RotationTransition(
turns: _controller, // от 0 к 1 (0 к 360 градусам)
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
SizedBox(height: 30),
ElevatedButton(
onPressed: () {
_controller.forward();
},
child: Text('Вращать'),
),
],
),
),
);
}
}
Пример 3: Несколько анимаций одновременно
class MultipleAnimationsExample extends StatefulWidget {
@override
State<MultipleAnimationsExample> createState() => _MultipleAnimationsExampleState();
}
class _MultipleAnimationsExampleState extends State<MultipleAnimationsExample>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
late Animation<double> _opacityAnimation;
late Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this,
);
// Масштабирование
_scaleAnimation = Tween<double>(begin: 0.5, end: 1.5).animate(
CurvedAnimation(parent: _controller, curve: Curves.elasticInOut),
);
// Прозрачность
_opacityAnimation = Tween<double>(begin: 0, end: 1).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeIn),
);
// Смещение
_slideAnimation = Tween<Offset>(
begin: Offset(-1, 0),
end: Offset(0, 0),
).animate(
CurvedAnimation(parent: _controller, curve: Curves.easeOut),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return SlideTransition(
position: _slideAnimation,
child: Opacity(
opacity: _opacityAnimation.value,
child: Transform.scale(
scale: _scaleAnimation.value,
child: Container(
width: 100,
height: 100,
color: Colors.green,
),
),
),
);
},
),
SizedBox(height: 30),
ElevatedButton(
onPressed: () => _controller.forward(),
child: Text('Анимировать'),
),
],
),
),
);
}
}
Встроенные Transition виджеты
// Flutter предоставляет готовые Transition компоненты
ScaleTransition(scale: animation, child: widget);
RotationTransition(turns: animation, child: widget);
SlideTransition(position: animation, child: widget);
FadeTransition(opacity: animation, child: widget);
SizeTransition(sizeFactor: animation, child: widget);
Пример 4: Повторяющаяся анимация
class RepeatingAnimationExample extends StatefulWidget {
@override
State<RepeatingAnimationExample> createState() => _RepeatingAnimationExampleState();
}
class _RepeatingAnimationExampleState extends State<RepeatingAnimationExample>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 1),
vsync: this,
);
// Повторять анимацию бесконечно
_controller.repeat(reverse: true); // туда-сюда
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ScaleTransition(
scale: Tween<double>(begin: 0.8, end: 1.2).animate(_controller),
child: Container(
width: 100,
height: 100,
color: Colors.purple,
),
),
),
);
}
}
Контроль анимации
// Методы AnimationController
_controller.forward(); // начало (от 0 к 1)
_controller.reverse(); // отмена (от 1 к 0)
_controller.stop(); // остановка
_controller.reset(); // сброс на начало
_controller.forward(from: 0.5); // начало с позиции 0.5
_controller.repeat(); // повторять
_controller.repeat(reverse: true); // туда-сюда
// Слушатели
_controller.addListener(() {
print('Значение: ${_controller.value}'); // от 0 к 1
});
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
print('Анимация завершена');
}
});
Когда использовать явные анимации
- Нужен полный контроль над анимацией
- Сложные анимации с несколькими этапами
- Анимации по действиям пользователя
- Требуется слушатель для срабатывания действий
- Необходимо управление временем (пауза, продолжение)
Явные анимации — это мощный инструмент для создания сложных и управляемых анимаций в Flutter.