As we are going to use GestureDetector() widget to setup tappable functionality, we must replace the return statement in the build(BuildContext context) method with return GestureDetector():
import 'package:flutter/widgets.dart';
class BouncingButton extends StatefulWidget {
final Function onTap;
final Widget child;
const BouncingButton({
Key key,
this.onTap,
this.child,
}) : super(key: key);
@override
_BouncingButtonState createState() => _BouncingButtonState();
}
class _BouncingButtonState extends State<BouncingButton> {
@override
Widget build(BuildContext context) {
return GestureDetector();
}
}
Focus on our __BouncingButtonStateclass _class. We use the ‘with’ keyword to reuse the behavior from the mixin class SingleTickerProviderStateMixin.
...
class _BouncingButtonState extends State<BouncingButton> with SingleTickerProviderStateMixin{
@override
Widget build(BuildContext context) {
return GestureDetector();
}
}
Inside our __BouncingButtonStateclass _class, create supporting variables as below:
→ Create a private variable of type AnimationController to control the animation behavior:
AnimationController _controller;
→ Create a ‘scale’ variable to keep track of how far the bouncing animation goes:
double _scale;
→ Setup AnimationController inside initState() method:
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 200),
lowerBound: 0.0,
upperBound: 0.1
)..addListener(() {
setState(() {});
});
}
duration: the animation duration
NOTE: vsync: this — won’t work if our class does not use the mixin class SingleTickerProviderStateMixin.
As we are going to use GestureDetector(), we need to prepare these two methods below in order to handle the gestures and animate our bouncing effects accordingly:
void _onTapDown(TapDownDetails details) {
_controller.forward();
}
void _onTapUp(TapUpDetails details) {
_controller.reverse();
}
#flutter #bouncing