class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin { late Animation<double> animation; late AnimationController controller; @override void initState(){ super.initState(); controller = AnimationController( duration: const Duration(seconds: 3), vsync: this ); animation = Tween<double>(begin: 0, end: pi*2) .animate(controller) ..addListener(() { setState((){ }); }); controller.repeat(reverse: false); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color.fromARGB(255, 255,255,255), appBar: AppBar( title: Text('App Name', style: TextStyle(fontSize: 30.0),), ), body: Center( child:Column( children: [ Padding(padding: EdgeInsets.all(10)), Container( width: 300, height: 300, child: CustomPaint( painter: MyPainter(animation.value), child: Center(), ), ), ], ), ), ); } } class MyPainter extends CustomPainter { final double value; MyPainter(this.value); @override void paint(Canvas canvas, Size size){ Paint p = Paint(); canvas.save(); p.style = PaintingStyle.fill; p.color = Color.fromARGB(100, 255, 0, 255); Rect r = Rect.fromLTWH(0,0,250,250); canvas.translate(150, 250); canvas.rotate(value); canvas.translate(-125, -125); canvas.drawRect(r, p); canvas.restore(); p.style = PaintingStyle.stroke; p.strokeWidth = 25; p.color = Color.fromARGB(100, 0, 255, 255); r = Rect.fromLTWH(0, 0, 250, 250); canvas.translate(150, 250); canvas.rotate(value * - 1); canvas.translate(-125, -125); canvas.drawRect(r, p); } @override bool shouldRepaint(CustomPainter oldDelegate) => true; }
アニメーションウィジェット
class _MyHomePageState extends State<MyHomePage> { bool flg = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('App Name', style: TextStyle(fontSize: 30.0),), ), body: Padding( padding: EdgeInsets.all(20), child:Column( children: [ AnimatedAlign( alignment: flg ? Alignment.topLeft : Alignment.topRight, duration: const Duration(seconds: 1), child: Container( color: Colors.red, width: 100, height: 100, ), curve: Curves.linear, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed:(){ setState((){ flg = !flg; }); }, child: const Icon(Icons.star), ), ); } }
AnimatedDefaultTextStyleによるテキスト操作
body: Padding( padding: EdgeInsets.all(20), child:Column( children: [ AnimatedDefaultTextStyle( duration: const Duration(seconds: 1), style: TextStyle( fontSize: flg ? 48 : 96, fontWeight: FontWeight.bold, color: flg ? Colors.red : Colors.blue ), child: Text("Hello Flutter"), ), ], ), ),
ウィジェットを動かす
body: Padding( padding: EdgeInsets.all(20), child:Stack( children: [ AnimatedPositioned( duration: const Duration(seconds: 3), top: flg ? 300 : 0, left: flg ? 0 : 300, child: Container( color: Colors.red, width: 100, height: 100, ) ), ], ), ),
AnimatedCrossFadeによるウィジェットの切り替え
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('App Name', style: TextStyle(fontSize: 30.0),), ), body: Padding( padding: EdgeInsets.all(20), child:Column( children: [ AnimatedCrossFade( duration: const Duration(seconds: 1), firstChild: const FlutterLogo( style: FlutterLogoStyle.horizontal, size: 300.0), secondChild: const FlutterLogo( style: FlutterLogoStyle.stacked, size: 300.0), crossFadeState: flg ? CrossFadeState.showFirst : CrossFadeState.showSecond, ), ], ), ),