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

转至:http://blog.csdn.net/shuaihj/article/details/46663109

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

<p>常见的,我们会在FragmentActivity中嵌套一层Fragment使用,甚至Fragment下层层嵌套使用。这个时候,在第二级或者更深级别的Fragment将无法收到onActivityResult回调,查看FragementActivity的源码发现:</p><pre class="prettyprint" sizset="0" sizcache="25" name="code"><code class="language-java hljs  has-numbering" sizset="29" sizcache="23"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startActivityFromFragment</span>(Fragment fragment, Intent intent,   
:             <span class="hljs-keyword">int</span> requestCode) { 
:         <span class="hljs-keyword">if</span> (requestCode == -<span class="hljs-number">1</span>) { 
:             <span class="hljs-keyword">super</span>.startActivityForResult(intent, -<span class="hljs-number">1</span>); 
:             <span class="hljs-keyword">return</span>; 
:         } 
:         <span class="hljs-keyword">if</span> ((requestCode&<span class="hljs-number">0xffff0000</span>) != <span class="hljs-number">0</span>) { 
:             <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Can only use lower 16 bits for requestCode"</span>); 
:         } 
:         <span class="hljs-keyword">super</span>.startActivityForResult(intent, ((fragment.mIndex+<span class="hljs-number">1</span>)<<<span class="hljs-number">16</span>) + (requestCode&<span class="hljs-number">0xffff</span>)); 
:     } 
:     <span class="hljs-annotation">@Override</span> 
:     <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onActivityResult</span>(<span class="hljs-keyword">int</span> requestCode, <span class="hljs-keyword">int</span> resultCode, Intent data) { 
:         mFragments.noteStateNotSaved(); 
:         <span class="hljs-keyword">int</span> index = requestCode>><span class="hljs-number">16</span>; 
:         <span class="hljs-keyword">if</span> (index != <span class="hljs-number">0</span>) { 
:             index--; 
:             <span class="hljs-keyword">if</span> (mFragments.mActive == <span class="hljs-keyword">null</span> || index < <span class="hljs-number">0</span> || index >= mFragments.mActive.size()) { 
:                 Log.w(TAG, <span class="hljs-string">"Activity result fragment index out of range: 0x"</span> 
:                         + Integer.toHexString(requestCode)); 
:                 <span class="hljs-keyword">return</span>; 
:             } 
:             Fragment frag = mFragments.mActive.get(index); 
:             <span class="hljs-keyword">if</span> (frag == <span class="hljs-keyword">null</span>) { 
:                 Log.w(TAG, <span class="hljs-string">"Activity result no fragment exists for index: 0x"</span> 
:                         + Integer.toHexString(requestCode)); 
:             } <span class="hljs-keyword">else</span> { 
:                 frag.onActivityResult(requestCode&<span class="hljs-number">0xffff</span>, resultCode, data); 
:             } 
:             <span class="hljs-keyword">return</span>; 
:         } 
:           
:         <span class="hljs-keyword">super</span>.onActivityResult(requestCode, resultCode, data); 
:     } 
:   </code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

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

<code class="language-java hljs  has-numbering" sizset="70" sizcache="23"><span class="hljs-keyword">public</span> <span class="hljs-class" sizset="72" sizcache="23"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseFragmentActiviy</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FragmentActivity</span> {</span>
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TAG = <span class="hljs-string">"BaseActivity"</span>;

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

 }

 <span class="hljs-javadoc" sizset="101" sizcache="23">/**
  * 递归调用,对所有子Fragement生效
  * 
  *<span class="hljs-javadoctag"> @param</span> frag
  *<span class="hljs-javadoctag"> @param</span> requestCode
  *<span class="hljs-javadoctag"> @param</span> resultCode
  *<span class="hljs-javadoctag"> @param</span> data
  */</span>
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleResult</span>(Fragment frag, <span class="hljs-keyword">int</span> requestCode, <span class="hljs-keyword">int</span> resultCode,
   Intent data) {
  frag.onActivityResult(requestCode & <span class="hljs-number">0xffff</span>, resultCode, data);
  List<Fragment> frags = frag.getChildFragmentManager().getFragments();
  <span class="hljs-keyword">if</span> (frags != <span class="hljs-keyword">null</span>) {
   <span class="hljs-keyword">for</span> (Fragment f : frags) {
    <span class="hljs-keyword">if</span> (f != <span class="hljs-keyword">null</span>)
     handleResult(f, requestCode, resultCode, data);
   }
  }
 }</code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

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

<code class="language-java hljs  has-numbering" sizset="116" sizcache="23"><span class="hljs-javadoc" sizset="117" sizcache="23">/**
  * 得到根Fragment
  * 
  *<span class="hljs-javadoctag"> @return</span>
  */</span>
 <span class="hljs-keyword">private</span> Fragment <span class="hljs-title">getRootFragment</span>() {
  Fragment fragment = getParentFragment();
  <span class="hljs-keyword">while</span> (fragment.getParentFragment() != <span class="hljs-keyword">null</span>) {
   fragment = fragment.getParentFragment();
  }
  <span class="hljs-keyword">return</span> fragment;

 }

 <span class="hljs-javadoc">/**
  * 启动Activity
  */</span>
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClickTextViewRemindAdvancetime</span>() {
  Intent intent = <span class="hljs-keyword">new</span> Intent();
  intent.setClass(getActivity(), YourActivity.class);
  intent.putExtra(<span class="hljs-string">"TAG"</span>,<span class="hljs-string">"TEST"</span>); 
  getRootFragment().startActivityForResult(intent, <span class="hljs-number">1001</span>);
 }</code>
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值