Flutter非构造函数实现自定义FloatingActionButton与MainWidget数据双向传递
Flutter组件间非构造函数传递数据方案
针对你需要将自定义FloatingActionButton组件内对话框的输入内容传递到MainWidget的Text控件的需求,以下是几种无需构造函数的实现方案:
方案1:使用Notification通知机制
通过自定义Notification类,在FloatingActionButton的对话框中发送通知,MainWidget监听该通知并更新自身状态。
代码实现
- 定义自定义通知类
class InputDataNotification extends Notification { final String inputText; InputDataNotification(this.inputText); }
- 修改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(), ), ); } }
- 修改自定义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,让子组件可以通过上下文获取共享状态并修改,无需构造函数传递。
代码实现
- 定义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; } }
- 修改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(); } }
- 修改自定义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的状态实例,调用方法更新内容。此方式组件耦合度高,仅适合简单场景。
代码实现
- 定义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(), ); } }
- 修改自定义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
相关产品推荐
相关产品推荐

