前言:

Fragment也可以使用startActivityForResult方法去打开一个Activity,然后在其onActivityResult方法中处理结果,可是当Fragment嵌套的时候,由于FragmentActivity的BUG导致只会回调最外那层Fragment的onActivityResult方法,于是乎当前Fragment就收不到结果了。

BUG分析:

解决这个问题之前我们先通过源码分析一下是什么原因导致的,以22.2.1版本的support-v4库为例

我们先从Fragment的startActivityForResult开始分析

public void startActivityForResult(Intent intent, int requestCode) {if(this.mActivity == null) {throw new IllegalStateException("Fragment " + this + " not attached to Activity");} else {this.mActivity.startActivityFromFragment(this, intent, requestCode);}
}
复制代码

很明显直接调用了FragmentActivity的startActivityFromFragment方法

public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {if(requestCode == -1) {super.startActivityForResult(intent, -1);} else if((requestCode & -65536) != 0) {throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");} else {super.startActivityForResult(intent, (fragment.mIndex + 1 << 16) + (requestCode & '\uffff'));}
}
复制代码

在这里将requestCode和Fragment的mIndex融合成了一个整型作为新的requestCode,那么新的requestCode的高16位表示Fragment的索引,低16为表示原本的requestCode,看来这里是用Fragment的mIndex作为查找依据的

接下来再看FragmentActivity的onActivityResult方法

protected void onActivityResult(int requestCode, int resultCode, Intent data) {this.mFragments.noteStateNotSaved();int index = requestCode >> 16;if(index != 0) {--index;if(this.mFragments.mActive != null && index >= 0 && index < this.mFragments.mActive.size()) {Fragment frag = (Fragment)this.mFragments.mActive.get(index);if(frag == null) {Log.w("FragmentActivity", "Activity result no fragment exists for index: 0x" + Integer.toHexString(requestCode));} else {frag.onActivityResult(requestCode & '\uffff', resultCode, data);}} else {Log.w("FragmentActivity", "Activity result fragment index out of range: 0x" + Integer.toHexString(requestCode));}} else {super.onActivityResult(requestCode, resultCode, data);}
}
复制代码

在这里取出requestCode的高16位,不等0就是子Fragment的mIndex,但是接下来却直接从Activity的Fragment列表中根据索引去找Fragment,如果你的Fragment是被子Fragment的childFragmentManager管理的话这样是绝对找不到的,于是乎答案很明了了。

解决问题:

解决这个问题的办法有两个 第一个是直接升级support-v4到23.2.0以上的版本,因为23.2.0以上就修复了这个BUG,具体怎么解决的就不再赘述了有兴趣的可自行研究,但由于种种原因没办法升级23.2.0的还大有人在 第二种办法就是自己动手丰衣足食,在Fragment层重写相关方法解决问题

接下来着重介绍自己动手丰衣足食的办法,完整实现如下:

public class ForResultNestedCompatFragment extends Fragment {private ForResultNestedCompatFragment forResultChildFragment;@Overridepublic void startActivityForResult(Intent intent, int requestCode) {Fragment parentFragment = getParentFragment();if (parentFragment != null && parentFragment instanceof ForResultNestedCompatFragment) {((ForResultNestedCompatFragment) parentFragment).startActivityForResultFromChildFragment(intent, requestCode, this);} else {forResultChildFragment = null;super.startActivityForResult(intent, requestCode);}}private void startActivityForResultFromChildFragment(Intent intent, int requestCode, ForResultNestedCompatFragment childFragment) {forResultChildFragment = childFragment;Fragment parentFragment = getParentFragment();if (parentFragment != null && parentFragment instanceof ForResultNestedCompatFragment) {((ForResultNestedCompatFragment) parentFragment).startActivityForResultFromChildFragment(intent, requestCode, this);} else {super.startActivityForResult(intent, requestCode);}}@Overridepublic final void onActivityResult(int requestCode, int resultCode, Intent data) {if (forResultChildFragment != null) {forResultChildFragment.onActivityResult(requestCode, resultCode, data);forResultChildFragment = null;} else {onActivityResultNestedCompat(requestCode, resultCode, data);}}public void onActivityResultNestedCompat(int requestCode, int resultCode, Intent data) {}
}
复制代码

具体思路一句话概括就是startActivityForResult的时候一层一层往上让父Fragment持有子Fragment的引用,回调onActivityResult的时候父Fragment再一层一层传给子Fragment

具体用法就是让所有的Fragment都继承ForResultNestedCompatFragment,然后用onActivityResultNestedCompat方法替换onActivityResult方法

如果你觉得有用,就点个喜欢吧!

转载于:https://juejin.im/post/5cb41f7af265da03474df4c3

【Android Fragment】解决Fragment多层嵌套时onActivityResult无法正确回调的问题相关推荐

  1. Bootstrap中模态框多层嵌套时滚动条问题

    在使用Bootstrap中模态框过程中,如果出现多层嵌套的时候,如打开模态框A,然后在A中打开模态框B,在关闭B之后,如果A的内容比较多,滚动条会消失,而变为Body的滚动条,这是由于模态框自带的遮罩 ...

  2. 【Android自定义控件】支持多层嵌套RadioButton的RadioGroup

    前言 非常喜欢用RadioButton+RadioGroup做Tabs,能自动处理选中等效果,但是自带的RadioGroup不支持嵌套RadioButton(从源码可看出仅仅是判断子控件是不是Radi ...

  3. Android studio aar包多层嵌套,Add library ‘Gradle: __local_aars__: 。。。unspecified@jar‘ to classpath

    编译出错报的日志: FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':to ...

  4. iframe多层嵌套时获取元素总结

    父页面获取子页面元素: 注意:onload事件 jQuery获取: $("iframe").contents().find("holder")......; ( ...

  5. Android多层嵌套Fragment中调用系统相机拍照以及裁剪的相关问题解决

    多层嵌套Fragment中调用系统相机拍照.裁剪 最近公司项目有频繁使用相机拍照的需求,然后频繁的实际使用过程中遇到很多大大小小的坑,在此记录下. (ps.关于一些拍照后图片旋转.裁剪设置返回数据为t ...

  6. android viewpager 嵌套fragment,Android ViewPager+Fragment多层嵌套(使用问题处理)

    之前写了Android ViewPager+Fragment(使用问题处理),封装了一个BaseFragment,对于简单使用ViewPager+Fragment而言,是没有问题的. 不过,ViewP ...

  7. android viewpager fragment传值,Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题...

    前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapt ...

  8. Android底部导航框架(解决fragment界面重现,getActivity空指针)

    android底部导航框架可以说是目前最常用的框架,看似非常简单的框架如果搭建不好后期会出现各种意想不到问题: 比如我前面两篇写的每次点击底部图标fragment之间会来回替换,这样肯定不实用:这个d ...

  9. 解决Bug:关于折叠屏手机(Android)出现fragment重叠问题

    文 | Promise Sun 一.Bug问题描述 关于安卓折叠手机出现fragment重叠问题: 运行手机:华为折叠手机(HUAWEI Mate X2,很贵的那款) Bug:使用华为折叠手机,当折叠 ...

最新文章

  1. ORACLE建表练习
  2. Android命令行工具logcat详细用法!
  3. php 安装oracle扩展,win PHP7安装oracle扩展
  4. java调试案例_Spring-boot的debug调试代码实例
  5. python学习---语法
  6. PHP: 关键字global 和 超全局变量$GLOBALS的用法、解释、区别
  7. android 技能标签功能_android专业技能总结.doc
  8. ROS学习笔记7(理解ROS服务和参数)
  9. CSS百分比实现高度占位自适应
  10. CIO圈子—CIO成长交流的平台
  11. cocos2dx打飞机项目笔记一:项目结构介绍
  12. oracle 获取awk报告,Oracle 使用 ass.awk 工具查看 system state dump 说明
  13. 装office2010时,装了msxml6仍提示要装msxml6
  14. 网络编程 write 阻塞和非阻塞下的区别
  15. GIT无法提交到码云。原因可能是所在提交位置不对
  16. 别瞎学了,我的MySQL学习之路(超详细超硬核)
  17. PPT打开之后不能编辑,怎么解决?
  18. java集合set不能去重_java集合去重和排序
  19. 关于ARM芯片中的大小端模式
  20. 2020年8月编程语言排行榜出炉:C语言位居第一,Java、Python位居二三

热门文章

  1. 用c语言计算2的n次方,计算2的N次方........有什么错吗?
  2. java仔_Java基础语法吐血整理
  3. 白鹭引擎android打包,白鹭引擎能把动画打包成小程序吗
  4. 为什么python的命名不能以数字开头,Python模块名称以数字开头
  5. mysql 备份 索引_mysql-索引、导入、导出、备份、恢复
  6. HIve常用CLI命令
  7. 一些加快 程序运行速度的方法
  8. SVO实时全局光照优化(里程碑MK2):Sparse Voxel Octree based Global Illumination (SVO GI)...
  9. linux_iptables 详解
  10. PyQt学习笔记(二)将PyQt项目转化为WIN下的可执行程序