转至: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>