Android的Fragment中onActivityResult不被调用的解决方案

 

 

  常见的,我们会在FragmentActivity中嵌套一层Fragment使用,甚至两次或多层Fragment嵌套使用。这个时候,在第二级或者更深级别的Fragment调用startActivityForResult方法时,将无法收到onActivityResult回调。阅读FragementActivity源码后发现,原来是源码里没有处理嵌套Fragment的情况,也就是说回调只到第一级Fragment,就没有继续分发。我们可以实现一个自己的AppCompatActivity,来实现继续分发,如下:

 

 1 public class CustomAppCompatActivity extends AppCompatActivity {
 2 
 3 
 4     private static final String TAG = "TAG";
 5 
 6 
 7     /**
 8      * 重写onactivityresult方法,使二个或多个fragment嵌套使用时能收到onactivityresut回调
 9      * @param requestCode
10      * @param resultCode
11      * @param data
12      */
13     @Override
14     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
15         FragmentManager fm = getSupportFragmentManager();
16         int index = requestCode >> 16;
17         if (index != 0) {
18             index--;
19             if (fm.getFragments() == null || index < 0
20                     || index >= fm.getFragments().size()) {
21                 Log.w(TAG, "Activity result fragment index out of range: 0x"
22                         + Integer.toHexString(requestCode));
23                 return;
24             }
25             Fragment frag = fm.getFragments().get(index);
26             if (frag == null) {
27                 Log.w(TAG, "Activity result no fragment exists for index: 0x"
28                         + Integer.toHexString(requestCode));
29             } else {
30                 handleResult(frag, requestCode, resultCode, data);
31             }
32             return;
33         }
34 
35     }
36 
37     /**
38      * 递归调用,对所有子Fragement生效
39      *
40      * @param frag
41      * @param requestCode
42      * @param resultCode
43      * @param data
44      */
45     private void handleResult(Fragment frag, int requestCode, int resultCode,
46                               Intent data) {
47         frag.onActivityResult(requestCode & 0xffff, resultCode, data);
48         List<Fragment> frags = frag.getChildFragmentManager().getFragments();
49         if (frags != null) {
50             for (Fragment f : frags) {
51                 if (f != null)
52                     handleResult(f, requestCode, resultCode, data);
53             }
54         }
55     }
56 
57 }

然后我们的Activity继承这个CustomAppCompatActivity即可,但是要注意,在Fragment中调用startActivityForResult时,一定要调用根Fragment的启动方法,如下:

 

/**
  * 得到根Fragment
  * 
  * @return
  */
 private Fragment getRootFragment() {
  Fragment fragment = getParentFragment();
  while (fragment.getParentFragment() != null) {
   fragment = fragment.getParentFragment();
  }
  return fragment;

 }

 /**
  * 启动Activity
  */
 private void onClickTextViewRemindAdvancetime() {
  Intent intent = new Intent();
  intent.setClass(getActivity(), YourActivity.class);
  intent.putExtra("TAG","TEST"); 
  getRootFragment().startActivityForResult(intent, 1000);
 }

附上github: https://github.com/974648183/CustomAppCompatActivity-

posted @ 2016-03-10 21:57  xjxmars  阅读(8742)  评论(0编辑  收藏  举报