在Flutter 中父组件调用子组件的方法可以通过GlobalKey
实现,而子组件调用父组件方法可以通过回调函数实现。
父组件
class _MyHomePageState extends State<MyHomePage> {final GlobalKey<LoadPencilState> loadPencilKey = GlobalKey<LoadPencilState>();// 动画状态bool isRun = false;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: Text(widget.title),),body: SizedBox(width: 350,child: Column(children: [LoadPencil(backgroundColor: Colors.blue,key: loadPencilKey,changeState: (state) {setState(() {isRun = state;});},),ElevatedButton(onPressed: () {if (isRun == true) {loadPencilKey.currentState?.stop();} else {loadPencilKey.currentState?.start();}},child: isRun == true ? const Text("停止") : const Text("开始")),],),));}
}
子组件
import 'package:flutter/material.dart';class LoadPencil extends StatefulWidget {final Color backgroundColor;final Function(bool state) changeState;const LoadPencil({super.key, required this.backgroundColor, required this.changeState});@overrideState<StatefulWidget> createState() => LoadPencilState();
}class LoadPencilState extends State<LoadPencil>with SingleTickerProviderStateMixin {// 定义动画控制器对象late AnimationController _controller;// 定义一个动画对象late Animation _animation;double _size = 0;@overridevoid initState() {super.initState();_controller = AnimationController(vsync: this,duration: const Duration(seconds: 2),);final Tween tween = Tween(begin: 0, end: 300);_animation = tween.animate(_controller);// 监听动画帧的变化,在每一帧中更新UI_animation.addListener(() {setState(() {_size = _animation.value.toDouble();});});// 监听动画的状态,当动画正序完成后反向执行动画_controller.addStatusListener((status) {// 动画状态status的值有:dismissed(动画停止在开始处)、forward(正向运行)、reverse(反向运行)、completed(动画停止在结束处)if (status == AnimationStatus.completed) {_controller.reverse();} else if (status == AnimationStatus.dismissed) {_controller.forward();}});}@overridevoid dispose() {super.dispose();//释放动画_controller.dispose();}@overrideWidget build(BuildContext context) {return Container(width: _size,height: 2,color: widget.backgroundColor,);}// 启动start() {_controller.forward();// 向父组件通信widget.changeState(true);}// 终止stop() {_controller.stop();// 向父组件通信widget.changeState(false);}
}
有一个需要注意的地方是,在使用GlobalKey<>
设置类型时,这个类型子组件的State
,而不是子组件本身
final GlobalKey<LoadPencilState> loadPencilKey = GlobalKey<LoadPencilState>();