这段代码展示了在 Flutter 中如何在父组件和子组件之间传递数据和触发命令,并根据命令在子组件中进行相应的操作和更新界面显示
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class ChildData {
int passedValue = 0;
String test = '';
//bool cmd = false;
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: ParentWidget(),
);
}
}
class ParentWidget extends StatefulWidget {
_ParentWidgetState createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
ChildData childData = ChildData();
int cmd = 0;
void actChild(String cmdIName) {
int cmdIn = 0;
if (cmdIName == '函数1')
cmdIn = 0;
else if (cmdIName == '函数2') cmdIn = 1;
if (cmdIn == 0x00) {
childData.passedValue = 10; //数据
} else if (cmdIn == 0x01) {
childData.test = 'ok'; //数据
}
cmd = (cmdIn << 8) | (~cmd & 0x01);
setState(() {});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Parent Widget'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Passed value: ${childData.passedValue}'),
ElevatedButton(
onPressed: () {
actChild('函数1');
},
child: Text('改变子窗口数据'),
),
ElevatedButton(
onPressed: () {
actChild('函数2');
},
child: Text('调用子窗口命令'),
),
ChildWidget(
childData: childData,
cmd: cmd,
),
],
),
),
);
}
}
class ChildWidget extends StatefulWidget {
final ChildData childData;
final int cmd;
ChildWidget({
required this.childData,
required this.cmd,
});
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
int cmdID = 0;
void initState() {
super.initState();
}
void didUpdateWidget(covariant ChildWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.cmd != widget.cmd) {
//print(widget.cmd);
if ((widget.cmd >> 8) == 0x00) {
//先处理数据再刷新界面
widget.childData.test += '${widget.cmd}';
setState(() {
cmdID++;
});
} else if ((widget.cmd >> 8) == 0x01) {
//先处理数据再刷新界面
if (widget.childData.passedValue == 10)
widget.childData.passedValue = 20;
else
widget.childData.passedValue = 10;
setState(() {});
}
}
}
Widget build(BuildContext context) {
return Container(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Text(
'Child Widget - Received value: ${widget.childData.passedValue}, cmdID:$cmdID'),
Text('Child Widget - Received value: ${widget.childData.test}'),
]),
);
}
}
以下是对这段代码的分析:
一、整体结构
首先引入了 Flutter 的基础材料包 material.dart,以便使用 Flutter 的 Material Design 风格组件。
定义了一个入口函数 main,在其中调用 runApp 函数并传入 MyApp 实例,启动整个 Flutter 应用。
二、ChildData 类
定义了一个用于在父组件和子组件之间传递数据的类,包含一个整数 passedValue、一个字符串 test 和一个注释掉的布尔值 cmd。
三、MyApp 类
MyApp 类继承自 StatelessWidget,表示这是一个无状态的组件。
在 build 方法中,返回一个 MaterialApp 实例,设置了应用的首页为 ParentWidget。
四、ParentWidget 类
ParentWidget 类继承自 StatefulWidget,表示这是一个有状态的组件。
在 createState 方法中,返回一个 _ParentWidgetState 实例,用于管理该组件的状态。
_ParentWidgetState 类:
定义了一个 ChildData 类型的变量 childData 和一个整数变量 cmd。
actChild 方法:根据传入的字符串参数 cmdIName 确定一个命令值 cmdIn,然后根据命令值修 改 childData 的内容,并更新 cmd。最后通过调用 setState 触发组件重新构建。
build 方法:
返回一个 Scaffold 实例,包含一个标题为 ‘Parent Widget’ 的 AppBar、一个居中显示的 Column 作为主体内容。Column 中包含一个显示从子组件传递过来的 passedValue 的 Text、两个 ElevatedButton(分别用于调用 actChild 方法传入不同的参数来改变子组件的数据或调用子组件的命 令)以及一个 ChildWidget 子组件,将 childData 和 cmd 传递给子组件。
五、ChildWidget 类
ChildWidget 类继承自 StatefulWidget,表示这是一个有状态的组件。
在构造函数中接收 childData 和 cmd 作为参数。
_ChildWidgetState 类:
定义了一个整数变量 cmdID。
initState 方法:
在组件初始化时被调用,可以在这里进行一些初始化操作。
didUpdateWidget 方法:当父组件触发重新构建导致子组件也更新时被调用。在这里,通过比较 新旧 cmd 的值来判断是否有变化,如果有变化,则根据 cmd 的高 8 位确定执行的操作,修改 childData 的内容,并通过 setState 触发子组件的重新构建。
build 方法:
返回一个 Container,包含两个 Text 分别显示从父组件传递过来的 passedValue 和 test,以及 cmdID。