前言
fragment 1.3.0-alpha04
发布了,其中有很多变动,其中提供了 fragment 间传递数据的新方式
1.3.0-alpha04 更新
API 更改
首先我们介绍一下 API 更改
-
startActivityForResult()
/onActivityResult()
和 requestPermissions()
/onRequestPermissionsResult()
弃用 -
prepareCall()
重命名为 registerForActivityResult()
-
target fragment API
被弃用
Activity Result API 上位
由于官方提供了 「Activity Result API」 来替换 「onActivityResult」 机制,因此 fragment 的 startActivityForResult()
/onActivityResult()
和 requestPermissions()
/onRequestPermissionsResult()
方法被标记弃用了
「Activity Result API」 详情可参考 秉心说 的 是时候丢掉 onActivityResult 了 !
文章介绍的很详尽,这里不再赘述
prepareCall 重命名
值得注意的地方是 prepareCall()
被命名为 registerForActivityResult()
❝
注意:在版本处于 Alpha 版状态时,可以添加、移除或更改 API。因此 Alpha 版本不适合在生产上使用
❞
来自我的另一篇博客
target fragment API 被弃用
其实 target fragment API
早已被弃用
setTargetFragment 被弃用
target fragment
需要直接访问另一个 fragment 的实例,这是十分危险的,因为你不知道目标 fragment 处于什么状态。而且 target fragment
不支持 Navigation
弃用 target fragment API
那么,fragment 之间传递数据更干净的方式是什么呢?
fragment 之间传递数据的新方式
前文提到,在相同的 FragmentManager 中可以使用 target fragment API 来在 fragment 间传递数据,但这种方式需要直接访问目标 fragment 的实例,这很危险,因为目标 fragment 的状态是未知的
因此官方提供了这样的 API,它允许在一个 fragment 上设置结果,并将该结果在 fragment 的适当的生命周期中使用。
这种传递数据的方式适用于 DialogFragment ,Navigation 中的 fragment
此更改还包括 -ktx 扩展功能以确保 kotlin 用户可以将 FragmentResultListener 作为 lambda 传递
FragmentA 源码FragmentB 源码demo
源码分析
老规矩,我们沿着官方的 commit log 来看看官方实现该功能的思路
首先,添加了 FragmentResultOwner 这样的的抽象,用于处理 fragment result,其内部有两个方法
- setResult
- setResultListener
前者用于发送数据,后者用于接收数据
FragmentResultOwner
而其实现类为 FragmentManager
FragmentManager implement FragmentResultOwner
我们来看看 FragmentManager 两个方法的具体实现
以上便是这部分的源码
❝
这里要注意一点的是
fragment result api
是基于同一 FragmentManager
的❞
总结
官方一直致力于将 fragment 的 api 变得更好用
Ian Lake 在 Fragments: Past, Present, and Future (Android Dev Summit '19) 中提到了 fragment 间通信的问题,未来 fragment 会整合 fragment 自身和其内部 view 的生命周期,提供同一 FragmentManager 多返回栈的支持
看到 fragment result API
,我突然有个想法,如果将其应用到 Navigation 中是否是解决 Navigation 跳转返回后状态重置的一个方法呢?
各位小伙伴有什么想法欢迎评论区留言
扫码关注公众号【音视频开发进阶】,一起学习多媒体音视频开发~~~
喜欢就点个」吧 ▽