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类来控制方法调用父子组件对应方法。父子组件方法调用的方式还可以通过事件通知等方法实现调用。

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

相关推荐
清风徐来辽4 分钟前
Android 项目模型配置管理
android
帅得不敢出门30 分钟前
Gradle命令编译Android Studio工程项目并签名
android·ide·android studio·gradlew
problc1 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人9 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
2401_8658548810 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
帅得不敢出门11 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
lqj_本人13 小时前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
我又来搬代码了13 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任15 小时前
Mac和安卓手机互传文件(ADB)
android·macos
芦半山15 小时前
Android“引用们”的底层原理
android·java