You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter非构造函数实现自定义FloatingActionButton与MainWidget数据双向传递

Flutter组件间非构造函数传递数据方案

针对你需要将自定义FloatingActionButton组件内对话框的输入内容传递到MainWidget的Text控件的需求,以下是几种无需构造函数的实现方案:

方案1:使用Notification通知机制

通过自定义Notification类,在FloatingActionButton的对话框中发送通知,MainWidget监听该通知并更新自身状态。

代码实现

  1. 定义自定义通知类
class InputDataNotification extends Notification {
  final String inputText;

  InputDataNotification(this.inputText);
}
  1. 修改MainWidget,添加通知监听
class _MainWidgetState extends State<MainWidget> {
  String _displayText = "";

  @override
  Widget build(BuildContext context) {
    return NotificationListener<InputDataNotification>(
      onNotification: (notification) {
        setState(() {
          _displayText = notification.inputText;
        });
        return true; // 阻止通知向上传递
      },
      child: Scaffold(
        body: Container(
          child: Center(
            child: Text(_displayText),
          ),
        ),
        floatingActionButton: floatingActionButton(),
      ),
    );
  }
}
  1. 修改自定义FloatingActionButton,发送通知
class _floatingActionButtonState extends State<floatingActionButton> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        showDialog(
          context: context,
          builder: (context) {
            return StatefulBuilder(
              builder: (context, setState) {
                return AlertDialog(
                  content: Center(
                    child: Container(
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          TextField(
                            controller: _controller,
                            decoration: const InputDecoration(hintText: "输入内容"),
                          ),
                          IconButton(
                            onPressed: () {
                              InputDataNotification(_controller.text).dispatch(context);
                              Navigator.pop(context);
                            },
                            icon: const Icon(Icons.send)
                          )
                        ],
                      ),
                    ),
                  ),
                );
              },
            );
          },
        );
      },
      child: const Icon(Icons.add),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

方案2:使用ValueNotifier + InheritedWidget共享状态

通过InheritedWidget包裹ValueNotifier,让子组件可以通过上下文获取共享状态并修改,无需构造函数传递。

代码实现

  1. 定义InheritedWidget提供状态
class InputValueProvider extends InheritedWidget {
  final ValueNotifier<String> inputValue;

  const InputValueProvider({
    super.key,
    required this.inputValue,
    required super.child,
  });

  static InputValueProvider? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<InputValueProvider>();
  }

  @override
  bool updateShouldNotify(covariant InputValueProvider oldWidget) {
    return inputValue != oldWidget.inputValue;
  }
}
  1. 修改MainWidget,包裹共享状态并监听变化
class _MainWidgetState extends State<MainWidget> {
  final ValueNotifier<String> _inputValue = ValueNotifier("");

  @override
  Widget build(BuildContext context) {
    return InputValueProvider(
      inputValue: _inputValue,
      child: Scaffold(
        body: Container(
          child: Center(
            child: ValueListenableBuilder<String>(
              valueListenable: _inputValue,
              builder: (context, value, child) {
                return Text(value);
              },
            ),
          ),
        ),
        floatingActionButton: floatingActionButton(),
      ),
    );
  }

  @override
  void dispose() {
    _inputValue.dispose();
    super.dispose();
  }
}
  1. 修改自定义FloatingActionButton,获取并修改共享状态
class _floatingActionButtonState extends State<floatingActionButton> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final inputValue = InputValueProvider.of(context)?.inputValue;
    return FloatingActionButton(
      onPressed: () {
        showDialog(
          context: context,
          builder: (context) {
            return StatefulBuilder(
              builder: (context, setState) {
                return AlertDialog(
                  content: Center(
                    child: Container(
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          TextField(
                            controller: _controller,
                            decoration: const InputDecoration(hintText: "输入内容"),
                          ),
                          IconButton(
                            onPressed: () {
                              if (inputValue != null) {
                                inputValue.value = _controller.text;
                              }
                              Navigator.pop(context);
                            },
                            icon: const Icon(Icons.send)
                          )
                        ],
                      ),
                    ),
                  ),
                );
              },
            );
          },
        );
      },
      child: const Icon(Icons.add),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

方案3:使用GlobalKey(不推荐,耦合度高)

通过GlobalKey直接获取MainWidget的状态实例,调用方法更新内容。此方式组件耦合度高,仅适合简单场景。

代码实现

  1. 定义GlobalKey并关联MainWidget
final GlobalKey<_MainWidgetState> _mainKey = GlobalKey<_MainWidgetState>();

class MainWidget extends StatefulWidget {
  const MainWidget({super.key}) : super(key: _mainKey);

  @override 
  State<MainWidget> createState() => _MainWidgetState();
}

class _MainWidgetState extends State<MainWidget> {
  String _displayText = "";

  void updateText(String text) {
    setState(() {
      _displayText = text;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: Text(_displayText),
        ),
      ),
      floatingActionButton: floatingActionButton(),
    );
  }
}
  1. 修改自定义FloatingActionButton,调用MainWidget的更新方法
class _floatingActionButtonState extends State<floatingActionButton> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        showDialog(
          context: context,
          builder: (context) {
            return StatefulBuilder(
              builder: (context, setState) {
                return AlertDialog(
                  content: Center(
                    child: Container(
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          TextField(
                            controller: _controller,
                            decoration: const InputDecoration(hintText: "输入内容"),
                          ),
                          IconButton(
                            onPressed: () {
                              _mainKey.currentState?.updateText(_controller.text);
                              Navigator.pop(context);
                            },
                            icon: const Icon(Icons.send)
                          )
                        ],
                      ),
                    ),
                  ),
                );
              },
            );
          },
        );
      },
      child: const Icon(Icons.add),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

内容的提问来源于stack exchange,提问作者ali ma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:44:55