flutter开发实战-父子Widget组件调用方法

flutter开发实战-父子Widget组件调用方法

在最近开发中遇到了需要父组件调用子组件方法,子组件调用父组件的方法。这里记录一下方案。

一、使用GlobalKey

父组件使用globalKey.currentState调用子组件具体方法,子组件通过方法回调callback方法调用父组件的方法。

例如示例中的

例如父组件

父组件使用globalKey.currentState调用子组件方法

globalKey.currentState?.subFunction(arg);

class FatherOutContainer extends StatefulWidget {
  const FatherOutContainer({super.key});

  @override
  State<FatherOutContainer> createState() => _FatherOutContainerState();
}

class _FatherOutContainerState extends State<FatherOutContainer> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  // 这里是父组件方法
  void fatherFunction(String param) {
    print("这里是父组件方法 params:${param}");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 375,
      height: 600,
      color: Colors.amber,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SizedBox(
            width: 20,
            height: 100,
          ),
          SubChild(
            key: globalKey,
            onPressedCallback: (param) {
              fatherFunction(param);
            },
          ),
          SizedBox(
            width: 20,
            height: 40,
          ),
          TextButton(
            child: Text("点击调用子组件方法"),
            onPressed: () {
              String arg = "来自父组件的参数";
              globalKey.currentState?.subFunction(arg);
            },
          ),
          Expanded(child: Container()),
        ],
      ),
    );
  }
}

子组件代码

子组件通过方法回调onPressedCallback方法调用父组件的方法。

onPressedCallback: (param) {

fatherFunction(param);

},

GlobalKey<_SubChildState> globalKey = GlobalKey();

// 子组件Widget
class SubChild extends StatefulWidget {
  const SubChild({
    super.key,
    required this.onPressedCallback,
  });

  final Function(String param) onPressedCallback;

  @override
  State<SubChild> createState() => _SubChildState();
}

class _SubChildState extends State<SubChild> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  // 这里是子组件方法
  void subFunction(String arg) {
    print("这里是子组件方法 arg:${arg}");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 300,
      height: 300,
      color: Colors.greenAccent,
      child: Container(
        width: 200,
        height: 50,
        child: TextButton(
          child: Text("点击调用父组件方法", style: TextStyle(
            color: Colors.brown
          ),),
          onPressed: () {
            onSubBtnPressed();
          },
        ),
      )
    );
  }

  // 点击调用父组件方法
  void onSubBtnPressed() {
    print("点击调用父组件方法");
    String param = "来自子组件的参数";
    widget.onPressedCallback(param);
  }
}

二、使用Controller,中间控制器

2.1、定义Controller,这里定义中间的方法调用的类

// 使用Controller类来调用方法
class MethodController {
  // 用此方法调用子组件方法
  Function(String arg)? dealSubFunction;

  // 用此方法调用父组件方法
  Function(String arg)? dealFatherFunction;
}

2.2、父组件代码

父组件通过定义methodController.dealFatherFunction,子组件可以调用该方法进行调用父组件的方法

// 定义
methodController.dealFatherFunction = (String arg) {
      // 调用父组件方法
      fatherFunction(arg);
    };

父组件完整代码

class FatherOutContainer extends StatefulWidget {
  const FatherOutContainer({super.key});

  @override
  State<FatherOutContainer> createState() => _FatherOutContainerState();
}

class _FatherOutContainerState extends State<FatherOutContainer> {
  final MethodController methodController = MethodController();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    methodController.dealFatherFunction = (String arg) {
      // 调用父组件方法
      fatherFunction(arg);
    };
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  // 这里是父组件方法
  void fatherFunction(String param) {
    print("这里是父组件方法 params:${param}");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 375,
      height: 600,
      color: Colors.amber,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SizedBox(
            width: 20,
            height: 100,
          ),
          SubChild(
            methodController: methodController,
          ),
          SizedBox(
            width: 20,
            height: 40,
          ),
          TextButton(
            child: Text("点击调用子组件方法"),
            onPressed: () {
              String arg = "来自父组件的参数";
              if (methodController.dealSubFunction != null) {
                methodController.dealSubFunction!(arg);
              }
            },
          ),
          Expanded(child: Container()),
        ],
      ),
    );
  }
}

2.3、子组件

子组件通过定义methodController.dealSubFunction,父组件可以调用该方法进行调用子组件的方法

// 定义
widget.methodController.dealSubFunction = (String arg) {
      // 调用子方法
      subFunction(arg);
    };

子组件完整代码

// 子组件Widget
class SubChild extends StatefulWidget {
  const SubChild({
    super.key,
    required this.methodController,
  });

  final MethodController methodController;

  @override
  State<SubChild> createState() => _SubChildState();
}

class _SubChildState extends State<SubChild> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    widget.methodController.dealSubFunction = (String arg) {
      // 调用子方法
      subFunction(arg);
    };
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  // 这里是子组件方法
  void subFunction(String arg) {
    print("这里是子组件方法 arg:${arg}");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        width: 300,
        height: 300,
        color: Colors.greenAccent,
        child: Container(
          width: 200,
          height: 50,
          child: TextButton(
            child: Text(
              "点击调用父组件方法",
              style: TextStyle(color: Colors.brown),
            ),
            onPressed: () {
              onSubBtnPressed();
            },
          ),
        ));
  }

  // 点击调用父组件方法
  void onSubBtnPressed() {
    print("点击调用父组件方法");
    String param = "来自子组件的参数";
    if (widget.methodController.dealFatherFunction != null) {
      widget.methodController.dealFatherFunction!(param);
    }
  }
}

三、小结

flutter开发实战-父子Widget组件调用方法。这里使用的Globalkey调用子组件方法,通过子组件的方法回调调用父组件的方法。还可以通过Controller类来控制方法调用父子组件对应方法。父子组件方法调用的方式还可以通过事件通知等方法实现调用。

学习记录,每天不停进步。

相关推荐
我又来搬代码了28 分钟前
【Android】application@label 属性属性冲突报错
android
用户268303689559744 分钟前
记录一次flutter项目更新到3.27
flutter
机器视觉小小测试员1 小时前
自动化测试工具Ranorex Studio(七十五)-录制ANDROID测试
android·测试工具·自动化
van叶~3 小时前
仓颉语言实战——2.名字、作用域、变量、修饰符
android·java·javascript·仓颉
m0_748239333 小时前
【PHP】部署和发布PHP网站到IIS服务器
android·服务器·php
小林爱3 小时前
【Compose multiplatform教程14】【组件】LazyColumn组件
android·前端·kotlin·android studio·框架·多平台
刘小哈哈哈3 小时前
实现一个iOS晃动动画
ios
牧杉-惊蛰4 小时前
html转PDF
android·pdf
yangfeipancc10 小时前
数据库-用户管理
android·数据库
字节流动10 小时前
Android Java 版本的 MSAA OpenGL ES 多重采样
android·java·opengles