Flutter 父子组件通信

在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>();

在这里插入图片描述
还有一个问题,需要主动获取时才能得到,比如点击按钮获取相应的值,如果是被动获取会获取不到,比如

 final GlobalKey<MenuListState> menuListKey = GlobalKey<MenuListState>();
 Text(menuListKey.currentState?.activePath ?? '11'),
Flutter 中,子组件(通常是一个 Widget)要调用父组件的方法,可以通过以下几种方式: 1. **通过`InheritedWidget`**:如果你的父组件实现了某个 `InheritedWidget`,子组件可以通过 `InheritedData` 获取到父组件的数据,并通过该数据调用父组件的函数。例如: ```dart class Parent extends StatelessWidget with InheritedWidget<ParentData> { @override ParentData get data => _data; // 父组件方法 void parentFunction() { // ... } @override Widget build(BuildContext context) { return Child( // 在Child中调用父方法 parentFunction(), ); } } // 子组件 Child class Child extends StatelessWidget { @override Widget build(BuildContext context) { // 如果需要调用父组件方法,使用 context.inheritedWidget.parentFunction(); } } ``` 2. **通过事件总线(Event Bus)**:如果子组件和父组件间没有直接的继承关系,可以使用事件总线如 `Provider` 或 `Riverpod` 来传递消息,父组件发布事件,子组件订阅并处理。 3. **回调函数(Callback)**:在构建子组件时,将需要调用的父组件方法作为参数传递。例如,使用 `onTap`、`onChanged` 等回调: ```dart class Parent extends StatefulWidget { final Function(String) onValueChange; @override _ParentState createState() => _ParentState(); } class _ParentState extends State<Parent> { void handleValueChange(String value) { // 父组件处理方法 } @override Widget build(BuildContext context) { return Container( child: RaisedButton( onPressed: () { // 触发回调 handleValueChange("from Child"); }, child: Text('Click me'), ), ); } } // 子组件 class Child extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( onPressed: () { // 调用父组件方法,传递参数 widget.onValueChange("from Child"); }, child: Text('Click me too'), ); } } ``` 相关问题--: 1. 如何在 Flutter 中使用 `InheritedWidget` 实现父子组件通信? 2. 什么是事件总线?在 Flutter 中如何使用它们来传递方法调用? 3. 何时会使用回调函数作为参数传递给子组件?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值