import 'package:flutter/material.dart';
class RotatingSquareScreen extends StatefulWidget {
@override
State<RotatingSquareScreen> createState() => _RotatingSquareScreenState();
}
class _RotatingSquareScreenState extends State<RotatingSquareScreen> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 4),
);
_animation = Tween<double>(begin: 0, end: 2 * 3.14159).animate(_controller);
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _toggleAnimation() {
if (_controller.isAnimating) {
_controller.stop();
} else {
_controller.repeat();
}
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Rotating Square Animation')),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Transform.rotate(
angle: _animation.value,
child: child,
);
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggleAnimation,
child: Icon(_controller.isAnimating ? Icons.pause : Icons.play_arrow),
tooltip: _controller.isAnimating ? 'Pause' : 'Play',
),
);
}
}
We create an AnimationController that runs for 4 seconds and loops continuously using repeat(). The Tween animates from 0 to 2π radians, representing a full rotation.
The AnimatedBuilder listens to the animation and rebuilds its child with a rotation transform. This way, the square rotates smoothly.
The floating action button toggles the animation on and off by starting or stopping the controller. The icon changes accordingly to show play or pause.
This example shows how AnimatedBuilder helps separate animation logic from widget building, making animations efficient and easy to manage.