详解Flutter中的数据传递

 更新时间:2021年04月06日 08:58:15   作者:移动的小太阳  
这篇文章主要介绍了Flutter中的数据传递的相关资料,帮助大家更好的理解和学习使用Flutter,感兴趣的朋友可以了解下

Flutter 中的数据传递

在开发中,数据从一个页面传递到另一个页面事很常用的,在Android 开发中,通常是通过把数据放到 intent 中传递过去。在 Flutter 中,数据是如何传递的呢?

在Flutter 中一切都是Widget,所以数据的传递就成了数据才Widget 中的传递。在之前的学习中,数据从一个Widget 传递到 子 Widget 是通过构造函数,一层一层的往里面传,要是 widget 的层级比较少,还没什么问题,要是层级很多,这样传递就太麻烦了。

还好Flutter 还提供了三种方案:InheritedWidget、Notification 和 EventBus来解决数据传递问题。

InheritedWidget

InheritedWidget 是 Flutter 中的一个功能型 Widget,适用于在 Widget 树中共享数据的场景。通过它,我们可以高效地将数据在 Widget 树中进行跨层传递。

下面看计数器的例子:

// 1.InheritedWidget,我们定义了一个继承自它的新类 CountContainer,里面存放需要共享的数据
//然后,我们将计数器状态 count 属性放到 CountContainer 中,并提供了一个 of 方法方便其子 Widget 在 Widget 树中找到它。
//最后,我们重写了 updateShouldNotify 方法,这个方法会在 Flutter 判断 InheritedWidget 是否需要重建,
class CountContainer extends InheritedWidget {
 static CountContainer of(BuildContext context) =>
   context.dependOnInheritedWidgetOfExactType<CountContainer>();
 final _InheritedWidgetHomeState mode;
 final Function() function;

 CountContainer(
   {Key key,
   @required this.mode,
   @required this.function,
   @required Widget child})
   : super(key: key, child: child);

 @override
 bool updateShouldNotify(covariant InheritedWidget oldWidget) {
  return this != oldWidget;
 }
}



// 2. 通过构建方法,把数据放到 InheritedWidget中
class _InheritedWidgetHomeState<InheritedWidgetHome> extends State {
 int count = 0;

 void _incrementCounter() => setState(() {
  count++;
 });

 @override
 Widget build(BuildContext context) {
  return CountContainer(
   mode: this,
   function: _incrementCounter,
   child: CountWidget(),
  );
 }
}

// 3. 在子 widget 通过 CountContainer.of方法,获取到自定义的 InheritedWidget,并从中取得共享的数据
class CountWidget extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
  CountContainer state = CountContainer.of(context);
  return Scaffold(
   appBar: AppBar(
    title: Text("InheritedWidget demo"),
   ),
   body: Text("current count is ${state.mode.count}"),
   floatingActionButton: FloatingActionButton(
    child: Icon(Icons.add),
    onPressed: state.function,
   ),
  );
 }
}

可以看到,InheritedWidget 的数据流动方式是从父 Widget 到子 Widget 逐层传递。

  1. 首先把通过构造函数需要共享的数据放到 InheritedWidget 中,然后提供一个静态方法,返回自身;
  2. 然后在把自定义的 InheritedWidget做为父容器,传入需要共享的数据;
  3. 最后在子widget 中,通过静态方法获取到 InheritedWidget 对象,自然就拿到里面的数据了。

EventBus

无论是 InheritedWidget 还是 Notificaiton,它们的使用场景都需要依靠 Widget 树,在使用起来就有点极限了,但Flutter 提供了一个更好的数据传递方法--EventBus,传递数据不再受到限制了。

在原生开发中,也有使用过 事件总线EventBus,Flutter 中实现跨组件通信的机制也是一样。它遵循发布 / 订阅模式,允许订阅者订阅事件,当发布者触发事件时,订阅者和发布者之间可以通过事件进行交互。发布者和订阅者之间无需有父子关系,甚至非 Widget 对象也可以发布 / 订阅。这些特点与其他平台的事件总线机制是类似的。

由于 EventBus是第三方库,所以需要引入:

event_bus: 2.0.0

从第二个页面,把数据回传到第一个页面

//建立公共的event bus
EventBus eventBus = EventBus();

class CustomEvent {
 String msg;

 CustomEvent(this.msg);
}

class _EventBusPager1State extends State {
 String message = "原来的数据";
 StreamSubscription subscription;

 @override
 void initState() {
  subscription = eventBus.on<CustomEvent>().listen((event) {
   setState(() {
    message = event.msg;
   });
  });
  super.initState();
 }

 @override
 Widget build(BuildContext context) {
  return Scaffold(
   appBar: AppBar(
    title: Text("EventBusPager1"),
   ),
   body: Center(
    child: Text(message),
   ),
   floatingActionButton: FloatingActionButton(
    child: Icon(Icons.open_in_browser),
    onPressed: () => Navigator.push(
      context, MaterialPageRoute(builder: (context) => EventBusPager2())),
   ),
  );
 }

 @override
 void dispose() {
  subscription.cancel();
  super.dispose();
 }
}

class EventBusPager2 extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
  return Scaffold(
   appBar: AppBar(
    title: Text("EventBusPager2"),
   ),
   body: Center(
    child: Text("EventBusPager1"),
   ),
   floatingActionButton: FloatingActionButton(
    child: Icon(Icons.send),
    onPressed: () {
     eventBus.fire(CustomEvent("data from page 2"));
     Navigator.pop(context);
    },
   ),
  );
 }
}

总结

通过学习了解了 在Flutter 中如何传递数据的,大致分为四种方式:

  1. 通过属性,一层一层往下传
  2. 通过 把数据写到 InheritedWidget的子类,然后把共享的数据放到里面,并提获取自身的供静态方法,在需要的地方通过静态方法获取到 InheritedWidget对象,并获取数据,这种方式是能从父widget 传递到子widget;
  3. 通过 Notifaction 发送消息,然后再父 widget 进行监听;
  4. 通过eventBus ,通过发布 / 订阅模式,来完成数据的传递,也是开发中常用的。

以上就是详解Flutter中的数据传递的详细内容,更多关于Flutter中的数据传递的资料请关注脚本之家其它相关文章!

相关文章

  • Android利用传感器实现微信摇一摇功能

    Android利用传感器实现微信摇一摇功能

    这篇文章主要为大家详细介绍了Android利用传感器实现微信摇一摇功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Android基础之常用控件属性介绍

    Android基础之常用控件属性介绍

    大家好,本篇文章主要讲的是Android基础之常用控件属性介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • Android中怎样避免创建不必要的对象

    Android中怎样避免创建不必要的对象

    对象的创建从来都不是免费的. 一个使用线程分配池的通用垃圾回收器可以让临时对象的分配变得廉价一些, 但是分配内存总是比不分配要昂贵得多.所以避免创建不必要的对象是很重要的一方面。
    2016-08-08
  • Android仿微信拍摄短视频

    Android仿微信拍摄短视频

    本文主要对Android仿微信拍摄短视频的实现方法进行介绍,其功能设置为类似于微信,点击开始拍摄,设置最长拍摄时间。具有很好的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • Android使用动画设置ProgressBar进度的方法

    Android使用动画设置ProgressBar进度的方法

    这篇文章主要为大家详细介绍了Android使用动画设置ProgressBar进度的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 详解Android平台上读写NFC标签

    详解Android平台上读写NFC标签

    NFC,即Near Field Communication,近距离无线通讯技术,是一种短距离的(通常<=4cm或更短)高频(13.56M Hz)无线通信技术,可以让消费者简单直观地交换信息、访问内容与服务。
    2017-01-01
  • Android自带emoji表情的使用方法详解

    Android自带emoji表情的使用方法详解

    这篇文章主要为大家详细介绍了Android自带emoji表情的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • LayoutAnimation给ListView中的item设置动态出场效果(实例)

    LayoutAnimation给ListView中的item设置动态出场效果(实例)

    下面小编就为大家带来一篇LayoutAnimation给ListView中的item设置动态出场效果(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 一分钟快速定位Android启动耗时问题

    一分钟快速定位Android启动耗时问题

    做开发除了实现功能,还要注重优化,性能优化包括的东西还是非常多的,下面这篇文章主要给大家介绍了关于如何通过一分钟快速定位Android启动耗时问题的相关资料,需要的朋友可以参考下
    2021-07-07
  • Kotlin之在Gradle中无参(no-arg)编译器插件的使用详解

    Kotlin之在Gradle中无参(no-arg)编译器插件的使用详解

    这篇文章主要介绍了Kotlin之在Gradle中无参(no-arg)编译器插件的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11

最新评论