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

常见的,我们会在FragmentActivity中嵌套一层Fragment使用,甚至Fragment下层层嵌套使用。这个时候,在第二级或者更深级别的Fragment将无法收到onActivityResult回调,查看FragementActivity的源码发现:

publicvoid startActivityFromFragment(Fragmentfragment, Intent intent,  

             int requestCode) {

         if (requestCode == -1) {

             super.startActivityForResult(intent, -1);

             return;

         }

         if ((requestCode&0xffff0000) != 0) {

             thrownew IllegalArgumentException("Can only use lower 16 bits for requestCode");

         }

         super.startActivityForResult(intent,((fragment.mIndex+1)<<16) + (requestCode&0xffff));

     }

     @Override

     protectedvoid 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, "Activityresult fragment index out of range: 0x"

                        + Integer.toHexString(requestCode));

                 return;

             }

            Fragment frag = mFragments.mActive.get(index);

             if (frag == null) {

                Log.w(TAG, "Activityresult no fragment exists for index: 0x"

                        + Integer.toHexString(requestCode));

             } else {

                 frag.onActivityResult(requestCode&0xffff, resultCode, data);

             }

             return;

         }

          

         super.onActivityResult(requestCode, resultCode,data);

     }

  

原来,程序猿偷懒,没有处理嵌套Fragment的情况,也就是说回调只到第一级Fragment,就没有继续分发。我们可以实现一个自己的FragmentActiviy,来实现继续分发,如下:

publicclassBaseFragmentActiviyextendsFragmentActivity {

 privatestaticfinal String TAG = "BaseActivity";

 

 @Override

 protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {

  FragmentManagerfm = getSupportFragmentManager();

  int index = requestCode >> 16;

  if (index != 0) {

   index--;

   if (fm.getFragments() == null || index < 0

     || index >=fm.getFragments().size()) {

    Log.w(TAG, "Activity result fragment index outof range: 0x"

      +Integer.toHexString(requestCode));

    return;

   }

   Fragment frag =fm.getFragments().get(index);

   if (frag == null) {

    Log.w(TAG, "Activity result no fragment existsfor index: 0x"

      +Integer.toHexString(requestCode));

   } else {

    handleResult(frag,requestCode, resultCode, data);

   }

   return;

  }

 

 }

 

 /**

  * 递归调用,对所有子Fragement生效

  *

  * @param frag

  * @param requestCode

  * @param resultCode

  * @param data

  */

 privatevoid handleResult(Fragment frag, int requestCode, int resultCode,

   Intent data) {

 frag.onActivityResult(requestCode & 0xffff, resultCode, data);

 List<Fragment> frags =frag.getChildFragmentManager().getFragments();

  if (frags != null) {

   for (Fragment f : frags) {

    if (f != null)

     handleResult(f,requestCode, resultCode, data);

   }

  }

 }

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

/**

  * 得到根Fragment

  *

  * @return

  */

 private Fragment getRootFragment() {

  Fragment fragment= getParentFragment();

  while (fragment.getParentFragment() != null) {

   fragment =fragment.getParentFragment();

  }

  return fragment;

 

 }

 

 /**

  * 启动Activity

  */

 privatevoid onClickTextViewRemindAdvancetime() {

  Intent intent = new Intent();

 intent.setClass(getActivity(), YourActivity.class);

  intent.putExtra("TAG","TEST");

 getRootFragment().startActivityForResult(intent, 1001);

 }


原文地址:http://blog.csdn.net/shuaihj/article/details/46663109

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Fragment 也可以通过 startActivityForResult() 方法启动另外一个 Activity,并通过 onActivityResult() 方法接收返回的数据。在 Fragment 使用 startActivityForResult() 方法时,要注意以下几点: 1. 需要在 Fragment 重写 onActivityResult() 方法,而不是在 Fragment 所依附的 Activity 重写。 2. 在 Fragment 启动 Activity 时,需要使用 getActivity().startActivityForResult() 方法,而不是直接使用 startActivityForResult() 方法。 3. 在 Fragment 接收返回数据时,需要调用 getActivity().onActivityResult() 方法,而不是直接调用 FragmentonActivityResult() 方法。 例如,以下是一个在 Fragment 使用 startActivityForResult() 方法的示例: ``` public class MyFragment extends Fragment { private static final int REQUEST_CODE = 100; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_my, container, false); } public void startMyActivity() { Intent intent = new Intent(getActivity(), MyActivity.class); startActivityForResult(intent, REQUEST_CODE); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) { String result = data.getStringExtra("result"); // 处理返回数据 } } @Override public void onResume() { super.onResume(); if (getActivity() instanceof MyActivity) { ((MyActivity) getActivity()).setResult(Activity.RESULT_OK, new Intent().putExtra("result", "Hello World!")); getActivity().finish(); } } } ``` 在上面的示例,我们在 Fragment 启动了一个名为 MyActivity 的 Activity,并在 Activity 模拟了返回数据的操作。当 Activity 被销毁时,会自动回调 FragmentonActivityResult() 方法,我们可以在该方法接收返回的数据并进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值