alighters

程序、写作、人生

nested-fragments-onAcitivityResult

| Comments

在执行嵌套的fragment(fragment里面嵌套fragment)的onActivityResult,会发现是执行不到的。所以接下来就fragmentActivity和fragment的源码类来分析一下他们具体的逻辑:

关键点:FragmentActivity的startActivityFromFragment方法

  1. FragmentActivity的startActivityForResult方法
1
2
3
4
5
6
public void startActivityForResult(Intent intent, int requestCode) {
        if (requestCode != -1 && (requestCode&0xffff0000) != 0) {
            throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
        }
        super.startActivityForResult(intent, requestCode);
    }

从上可以看出来,如果是通过调用Activity的这个方法,它只允许使用requestCode的低16为。

  1. FragmentAcitivity的startActivityFromFragment方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
  * Called by Fragment.startActivityForResult() to implement its behavior.
  */
 public void startActivityFromFragment(Fragment fragment, Intent intent,
         int requestCode) {
     if (requestCode == -1) {
         super.startActivityForResult(intent, -1);
         return;
     }
     if ((requestCode&0xffff0000) != 0) {
         throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
     }
     super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));
 }

这个方法是当调用fragment的startActivityForResult方法,便会调用到上面这个方法,这里做了一个处理是:将fragment的index(对应fragment在manager中对应的索引)放i在高16位,并保留低16位的requestCode.

  1. FragmentActivity的onActivityResult方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
  * Dispatch incoming result to the correct fragment.
  */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     mFragments.noteStateNotSaved();
     int index = requestCode>>16;
     if (index != 0) {
         index--;
         if (mFragments.mActive == null || index < 0 || index >= mFragments.mActive.size()) {
             Log.w(TAG, "Activity result fragment index out of range: 0x"
                     + Integer.toHexString(requestCode));
             return;
         }
         Fragment frag = mFragments.mActive.get(index);
         if (frag == null) {
             Log.w(TAG, "Activity result no fragment exists for index: 0x"
                     + Integer.toHexString(requestCode));
         } else {
             frag.onActivityResult(requestCode&0xffff, resultCode, data);
         }
         return;
     }

     super.onActivityResult(requestCode, resultCode, data);
 }

根据之前的逻辑,在这里就需要对高16位的数值,进行判断,当不为0时,根据对应的fragment的index值,获取到对应的fragment的onActivityResult方法。若高16位的数值为0,则表示是activity对应的方法。

解决之道

  1. fragment的层数
  2. 我们在这里可认为第一层的fragment(放在Activity之中),由getFragmentManager来管理
  3. 嵌套的fragment是通过getChildFragmentManager来获取的。
  4. 层数和index的存放 根据FragmentActivity存放fragment的index的原理,我们可以根据指定位数来存放fragment的层数以及index的相关信息。
  5. 代码(show me the code) 找到一篇github上的代码,就不贴我的代码了,思路就是这个思路。 nested-fragment-issue

版权归作者所有,转载请注明原文链接:/blog/2015/07/09/nested-fragments-onAcitivityResult/

给 Ta 个打赏吧...

Comments