这期内容当中小编将会给大家带来有关使用Flutter怎么对数据进行传递,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
在开发中,数据从一个页面传递到另一个页面事很常用的,在Android 开发中,通常是通过把数据放到 intent 中传递过去。在 Flutter 中,数据是如何传递的呢?
在Flutter 中一切都是Widget,所以数据的传递就成了数据才Widget 中的传递。在之前的学习中,数据从一个Widget 传递到 子 Widget 是通过构造函数,一层一层的往里面传,要是 widget 的层级比较少,还没什么问题,要是层级很多,这样传递就太麻烦了。
还好Flutter 还提供了三种方案:InheritedWidget、Notification 和 EventBus来解决数据传递问题。
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 逐层传递。
首先把通过构造函数需要共享的数据放到 InheritedWidget 中,然后提供一个静态方法,返回自身;
然后在把自定义的 InheritedWidget做为父容器,传入需要共享的数据;
最后在子widget 中,通过静态方法获取到 InheritedWidget 对象,自然就拿到里面的数据了。
无论是 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怎么对数据进行传递了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。