在Flutter 中父组件调用子组件的方法可以通过GlobalKey
实现,而子组件调用父组件方法可以通过回调函数实现。
父组件
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<LoadPencilState> loadPencilKey = GlobalKey<LoadPencilState>();
// 动画状态
bool isRun = false;
@override
Widget 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});
@override
State<StatefulWidget> createState() => LoadPencilState();
}
class LoadPencilState extends State<LoadPencil>
with SingleTickerProviderStateMixin {
// 定义动画控制器对象
late AnimationController _controller;
// 定义一个动画对象
late Animation _animation;
double _size = 0;
@override
void 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();
}
});
}
@override
void dispose() {
super.dispose();
//释放动画
_controller.dispose();
}
@override
Widget 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>();