Issue
I want the counter widget to show onTap
from home widget
. Also, start the animation
from start at every tap.
Counter Widget
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation<double> animation;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
)
..addListener(() => setState(() {}));
animation = CurvedAnimation(
parent: animationController,
curve: Curves.elasticOut,
);
animationController.forward();
}
@override
Widget build(BuildContext context) {
return ScaleTransition(
child: Container(
height: 100,
width: 100,
color: Colors.blue,
),
scale: animation,
);
}
}
Home Widget
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Center(
child: Counter(),
),
GestureDetector(
onTap: () {},
child: Container(
width: double.infinity,
height: double.infinity,
),
),
],
));
}
Solution
You need to define a GlobalKey
and pass it down to the child widget. This will enable you to access that Child’s methods and variables:
class HomeWidget extends StatefulWidget {
@override
_HomeWidgetState createState() => _HomeWidgetState();
}
class _HomeWidgetState extends State<HomeWidget> {
GlobalKey<CounterState> counterKey = GlobalKey<CounterState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Center(
child: Counter(key: counterKey),
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
counterKey.currentState.animationController.reverse();
},
child: Container(
width: double.infinity,
height: double.infinity,
),
),
],
)
);
}
}
class Counter extends StatefulWidget {
Counter({Key key}): super(key: key);
// This state must be public in order to access it.
@override
CounterState createState() => CounterState();
}
class CounterState extends State<Counter> with SingleTickerProviderStateMixin {
AnimationController animationController;
Animation<double> animation;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
)
..addListener(() => setState(() {}));
animation = CurvedAnimation(
parent: animationController,
curve: Curves.elasticOut,
);
animationController.forward();
}
@override
Widget build(BuildContext context) {
return ScaleTransition(
child: Container(
height: 100,
width: 100,
color: Colors.blue,
),
scale: animation,
);
}
}
Answered By – João Soares
Answer Checked By – David Goodson (FlutterFixes Volunteer)