flutter通过didUpdateWidget 实现父组件操控子组件

这段代码展示了在 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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值