Android的Fragment中onActivityResult不被调用的解决方案(绝对管用)

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

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startActivityFromFragment</span>(Fragment fragment, Intent intent,   
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> requestCode) { 
:         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (requestCode == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { 
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.startActivityForResult(intent, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); 
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; 
:         } 
:         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((requestCode&<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { 
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Can only use lower 16 bits for requestCode"</span>); 
:         } 
:         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.startActivityForResult(intent, ((fragment.mIndex+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)<<<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) + (requestCode&<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff</span>)); 
:     } 
:     <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> 
:     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onActivityResult</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> requestCode, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> resultCode, Intent data) { 
:         mFragments.noteStateNotSaved(); 
:         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> index = requestCode>><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>; 
:         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (index != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { 
:             index--; 
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mFragments.mActive == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || index < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> || index >= mFragments.mActive.size()) { 
:                 Log.w(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Activity result fragment index out of range: 0x"</span> 
:                         + Integer.toHexString(requestCode)); 
:                 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; 
:             } 
:             Fragment frag = mFragments.mActive.get(index); 
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (frag == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { 
:                 Log.w(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Activity result no fragment exists for index: 0x"</span> 
:                         + Integer.toHexString(requestCode)); 
:             } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { 
:                 frag.onActivityResult(requestCode&<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff</span>, resultCode, data); 
:             } 
:             <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; 
:         } 
:           
:         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onActivityResult(requestCode, resultCode, data); 
:     } 
:   </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

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

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">BaseFragmentActiviy</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FragmentActivity</span> {</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String TAG = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"BaseActivity"</span>;

 <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onActivityResult</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> requestCode, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> resultCode, Intent data) {
  FragmentManager fm = getSupportFragmentManager();
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> index = requestCode >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>;
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (index != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
   index--;
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (fm.getFragments() == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || index < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
     || index >= fm.getFragments().size()) {
    Log.w(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Activity result fragment index out of range: 0x"</span>
      + Integer.toHexString(requestCode));
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
   }
   Fragment frag = fm.getFragments().get(index);
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (frag == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
    Log.w(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Activity result no fragment exists for index: 0x"</span>
      + Integer.toHexString(requestCode));
   } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
    handleResult(frag, requestCode, resultCode, data);
   }
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
  }

 }

 <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
  * 递归调用,对所有子Fragement生效
  * 
  *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> frag
  *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> requestCode
  *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> resultCode
  *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> data
  */</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">handleResult</span>(Fragment frag, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> requestCode, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> resultCode,
   Intent data) {
  frag.onActivityResult(requestCode & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff</span>, resultCode, data);
  List<Fragment> frags = frag.getChildFragmentManager().getFragments();
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (frags != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Fragment f : frags) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (f != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>)
     handleResult(f, requestCode, resultCode, data);
   }
  }
 }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li></ul>

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

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
  * 得到根Fragment
  * 
  *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span>
  */</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Fragment <span class="hljs-title" style="box-sizing: border-box;">getRootFragment</span>() {
  Fragment fragment = getParentFragment();
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (fragment.getParentFragment() != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
   fragment = fragment.getParentFragment();
  }
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> fragment;

 }

 <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
  * 启动Activity
  */</span>
 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClickTextViewRemindAdvancetime</span>() {
  Intent intent = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Intent();
  intent.setClass(getActivity(), YourActivity.class);
  intent.putExtra(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TAG"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TEST"</span>); 
  getRootFragment().startActivityForResult(intent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1001</span>);
 }</code><p style="margin-top: 0px; margin-bottom: 1.1em; padding-top: 0px; padding-bottom: 0px; box-sizing: border-box; color: rgb(85, 85, 85); font-family: 'microsoft yahei'; font-size: 14px; line-height: 35px;">
</p>
<span style="color: rgb(85, 85, 85); font-family: 'microsoft yahei'; font-size: 14px; line-height: 35px;">
原文章地址:http://blog.csdn.net/shuaihj/article/details/46663109</span>
  • 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、付费专栏及课程。

余额充值