flutter 跨组件传递数据的三种方式

本文介绍了在Flutter中实现数据共享和通知的三种方法:inheritedWidget、notification和eventbus。详细展示了如何使用inheritedWidget进行状态管理和数据传递,以及notification机制在组件间发送和接收消息的具体实现。

三种方式

 1. inheritedWidget
 2. notification  
 3. eventbus 

inheritedWidget方式

class InheritedWidgetScreen extends StatefulWidget {
  InheritedWidgetScreen({Key key}) : super(key: key);


  @override
  _InheritedWidgetScreenState createState() => _InheritedWidgetScreenState();
}

class _InheritedWidgetScreenState extends State<InheritedWidgetScreen> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("inheritedWidget 使用"),
      ),
      body: Center(
        child: ShareWidget( //使用ShareWidget
          data: _counter,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(bottom: 20.0),
                child: Text('You have clicked the button this many time:'),
              ),
              Padding(
                padding: const EdgeInsets.only(bottom: 20.0),
                child: _TextWidget(), //子widget中依赖ShareWidget
              ),
              RaisedButton(
                child: Text('Increment'),
                onPressed: () => setState(() => ++_counter),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class ShareWidget extends InheritedWidget {

  final int data;

  ShareWidget({@required this.data, Widget child}) : super(child: child);

  //定义一个方法,方便子树中的widget获取这个widget,进而获得共享数据。
  static ShareWidget of(BuildContext context) {
    /**
     * 获取最近的给定类型的Widget,该widget必须是InheritedWidget的子类,
     * 并向该widget注册传入的context,当该widget改变时,
     * 这个context会重新构建以便从该widget获得新的值。
     * 这就是child向InheritedWidget注册的方法。
     */
    return context.inheritFromWidgetOfExactType(ShareWidget);
  }

  /**
   * framework通过使用以前占据树中的这个位置的小部件作为参数调用这个函数来区分这些情况。
   */
  @override
  bool updateShouldNotify(ShareWidget oldWidget) {
    return oldWidget.data != data;
  }
}

class _TextWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _TextWidgetState();
  }
}

class _TextWidgetState extends State<_TextWidget> {
  @override
  Widget build(BuildContext context) {
    return Text(
        ShareWidget
            .of(context)
            .data
            .toString()
    );
  }

  /**
   * 如果依赖的InheritedWidget改变了,framework将会调用这个方法来通知这个对象。
   * 在这个方法中调用BuildContext.inheritFromWidgetOfExactType是安全的。
   * 子类很少覆写这个方法,因为framework通常会在依赖的InheritedWidget改变后调用build方法,
   * 覆写这个方法通常用来做一些耗时的工作,比如网络请求
   */
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print("Dependencies change");
  }
}

notification 方式

	class NotificationScreen extends StatefulWidget {
	  NotificationScreen({Key key}) : super(key: key);
	
	  @override
	  _NotificationScreenState createState() => _NotificationScreenState();
	}
	
	class _NotificationScreenState extends State<NotificationScreen> {
	
	  @override
	  Widget build(BuildContext context) {
	    return Scaffold(
	        appBar: AppBar(
	          title: Text("Notification 使用"),
	        ),
	        body: NotificationListener(
	          onNotification: (notification) {
	            setState(() {
	              ToastUtil.showToast("上级接到了通知");
	            });
	            return true;
	          },
	          child: new RaisedButton(
	              textColor: Colors.black,
	              child: new Center(
	                child: new Text('点击传递随机数给上层Widget'),
	              ),
	              onPressed: () {
	                new TestNotification(count: new Random().nextInt(100))
	                    .dispatch(context);
	              }),
	        ));
	  }
	}
	
	class TestNotification extends Notification {
	  TestNotification({
	    @required this.count,
	  });
	
	  final int count;
	}

evenbus 的方式

       evenbus的方式请自行搜索

完整代码请访问

完整代码请访问GitHub

更多内容请关注公众号

在这里插入图片描述

Flutter 中,跨组件通信和状态管理有多种实现方法及相关技术: ### 事件总线(Event Bus) 事件总线是一种简单而有效的跨组件通信方式,它基于发布 - 订阅模式。在 Flutter 里可以使用 `event_bus` 库来实现。通过事件总线,一个组件可以发布事件,其他对该事件感兴趣的组件可以订阅这个事件并作出相应的处理。 ```dart import 'package:event_bus/event_bus.dart'; // 创建事件总线实例 EventBus eventBus = EventBus(); // 定义事件类 class MyEvent { final String message; MyEvent(this.message); } // 发布事件的组件 void publishEvent() { eventBus.fire(MyEvent('Hello from publisher!')); } // 订阅事件的组件 eventBus.on<MyEvent>().listen((event) { print('Received event: ${event.message}'); }); ``` ### InheritedWidget `InheritedWidget` 是 Flutter 中一个重要的用于跨组件共享数据的机制。它允许数据在 widget 树中从上往下递,子组件可以获取到上层 `InheritedWidget` 中存储的数据。 ```dart class MyInheritedWidget extends InheritedWidget { final int data; MyInheritedWidget({ required this.data, required Widget child, }) : super(child: child); static MyInheritedWidget? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>(); } @override bool updateShouldNotify(MyInheritedWidget oldWidget) { return data != oldWidget.data; } } // 在子组件中获取数据 class ChildWidget extends StatelessWidget { @override Widget build(BuildContext context) { final myData = MyInheritedWidget.of(context)?.data; return Text('Data from InheritedWidget: $myData'); } } ``` ### Provider `Provider` 是 Flutter 官方推荐的状态管理库,它是基于 `InheritedWidget` 实现的,使用起来更加方便和灵活。它可以帮助管理应用中的状态,并且可以在不同的组件之间共享这些状态。 ```dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; // 定义状态类 class MyModel with ChangeNotifier { int _counter = 0; int get counter => _counter; void increment() { _counter++; notifyListeners(); } } // 使用 Provider 提供状态 void main() { runApp( ChangeNotifierProvider( create: (context) => MyModel(), child: MyApp(), ), ); } // 在子组件中使用状态 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Provider Example')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Consumer<MyModel>( builder: (context, myModel, child) { return Text('Counter: ${myModel.counter}'); }, ), ElevatedButton( onPressed: () { Provider.of<MyModel>(context, listen: false).increment(); }, child: Text('Increment'), ), ], ), ), ), ); } } ``` ### Riverpod `Riverpod` 是另一个强大的状态管理库,它提供了更加简洁和可测试的状态管理方案。它允许开发者以声明式的方式管理状态,并且可以轻松地在不同组件之间共享状态。 ```dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; // 定义状态提供者 final counterProvider = StateProvider((ref) => 0); void main() { runApp( ProviderScope( child: MyApp(), ), ); } class MyApp extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final counter = ref.watch(counterProvider); return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Riverpod Example')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Counter: ${counter.state}'), ElevatedButton( onPressed: () { ref.read(counterProvider.notifier).state++; }, child: Text('Increment'), ), ], ), ), ), ); } } ``` Flutter 在设计中大量借鉴了前端架构理念,如组件化框架和全局状态管理器等,其提供的组件声明式框架有助于开发者进行跨组件开发,提高开发效率 [^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值