0.为什么有这个东西
今年年初启动的项目中计划使用JetPack的Navigation框架,于是如何在Fragment之间传递数据就成为了一个新的问题。
因为Fragment中并没有像Activity中setResult和onActivityResult这样的API,而且Navigation对此也是毫无支持。
虽然在最新的Fragment-1.3.0-alpha08中有新加入的API,但是你看到alpha几个字符后,还是算了吧。
于是自己琢磨出了一套方法,相比官方推荐的一系列方法中,这套方法拥有以下优势:
- 使用类型签名的方式进行匹配,不需要传递String类型的Key
- 直接传递任意类型的对象,不需要实现
Serializable或Parcelable接口 - 无需声明接口或ViewModel、LiveData等
1.引入方法
1.在你的android工程的根目录下的build.gradle文件中适当的位置添加以下代码:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
2.在你的模块下的build.gradle文件中的适当位置添加以下代码:
dependencies {
implementation 'com.gitee.numeron:mortar:0.1.0'
}
2.初始化
1.在启用Navigation的Activity中的onCreate方法中、setContentView之前,调用以下方法:
mortarEnabled()
3.使用方法
1.在要接收数据的AFragment中使用onResult方法:
onResult<List<User>> { resultCode: Int, list: List<User>? ->
if(resultCode == RESULT_OK) {
if(!list.isNullOrEmpty()) {
//TODO()
}
} else {
//TODO()
}
}
2.在要传递数据的BFragment中使用setResult方法:
val userList: List<User> = ...
setResult(RESULT_OK, userList)
3.当从BFragment返回到AFragment时,之前通过onResult方法设置的Lambda回调就会运行。
- 注:
onResult和setResult传递的参数的类型必需一致,MutableList和List是不一样的,当其中一个为MutableList时,应该将类型声明为具体的List类型。
4.原理解析
Mortar通过在FragmentManager中注册FragmentLifecycleCallbacks的方式来监听所有Fragment的生命周期,并在每个Fragment的onViewCreated方法时,查找该Fragment所等待的结果实例并处理回调。- 不管是
setResult方法传递的类型、还是onResult方法等待的类型,都会抽取出一个String类型的、表示具体类型的参数,这个参数会被封装到TypedValue或TypedCallback的实例中,这就是setResult和onResult之间进行匹配的关键所在。(这里参考了Gson)
5.结尾
以上两点就是整个Mortar的主要思路,目前已在公司的项目中稳定运行,欢迎start: github.com/xiazunyang/…