We’ll create a custom animated like button that changes color and size when pressed.
steps:
- We added with SingleTickerProviderStateMixin to the _NormalPageState class to enable animation capabilities.
- We introduced new variables for the animation:_controller: AnimationController to manage the animation._colorAnimation: Animation for changing the color of the like button._sizeAnimation: Animation for changing the size of the like button.isLiked: Boolean to track the liked state.
- In the initState method, we set up the animations:Created the AnimationController with a duration of 300 milliseconds.Set up the _colorAnimation to transition from grey to red.Created a _sizeAnimation that grows the icon and then shrinks it back to its original size.Added a listener to update the isLiked state based on the animation status.
- The AnimatedBuilder creates an IconButton with a heart icon (Icons.favorite). The color and size of this icon are controlled by our animations.
FULL CODE:
import 'package:flutter/material.dart'; class NormalPage extends StatefulWidget { const NormalPage({Key? key}) : super(key: key); @override State<NormalPage> createState() => _NormalPageState(); } class _NormalPageState extends State<NormalPage> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation<Color?> _colorAnimation; late Animation<double> _sizeAnimation; bool isLiked = false; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); _colorAnimation = ColorTween( begin: Colors.grey[400], end: Colors.red, ).animate(_controller); _sizeAnimation = TweenSequence<double>([ TweenSequenceItem(tween: Tween<double>(begin: 80, end: 100), weight: 50), TweenSequenceItem(tween: Tween<double>(begin: 100, end: 80), weight: 50), ]).animate(_controller); _controller.addStatusListener((status) { if (status == AnimationStatus.completed) { setState(() { isLiked = true; }); } if (status == AnimationStatus.dismissed) { setState(() { isLiked = false; }); } }); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("This is a title"), leading: IconButton( icon: const Icon(Icons.menu), onPressed: () {}, ), actions: <Widget>[ IconButton( icon: const Icon(Icons.comment), onPressed: () {}, ), IconButton( icon: const Icon(Icons.settings), onPressed: () {}, ), ], elevation: 1, ), body: Material( child: SafeArea( child: Center( child: AnimatedBuilder( animation: _controller, builder: (BuildContext context, _) { return GestureDetector( onTap: () { isLiked ? _controller.reverse() : _controller.forward(); }, child: Icon( Icons.favorite, color: _colorAnimation.value, size: _sizeAnimation.value, ), ); }, ), ), ), ), ); } }