fragment中onActivityResult 解决方法总结

来源:互联网 发布:武汉苏格淘宝女装拍摄 编辑:程序博客网 时间:2024/06/11 11:54

对于网上的解决方案做一个总结。

一,重写FragmentActivity

常见的,我们会在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>
二、通过在在fragment中获取当前fragment,重新调去fragment中onResultActivity方法

public class MyFragmentActivity extends FragmentActivity{                                   public FragmentTransaction mFragmentTransaction;    public FragmentManager fragmentManager;    public String curFragmentTag = "";.../*在fragment的管理类中,我们要实现这部操作,而他的主要作用是,当D这个activity回传数据到这里碎片管理器下面的fragnment中时,往往会经过这个管理器中的onActivityResult的方法。*/protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        /*在这里,我们通过碎片管理器中的Tag,就是每个碎片的名称,来获取对应的fragment*/        Fragment f = fragmentManager.findFragmentByTag(curFragmentTag);        /*然后在碎片中调用重写的onActivityResult方法*/        f.onActivityResult(requestCode, resultCode, data);    }...}
通过以下方法可获取到当前Fragment
public Fragment getVisibleFragment() {FragmentManager fragmentManager = getSupportFragmentManager();List<Fragment> fragments = fragmentManager.getFragments();for (Fragment fragment : fragments) {if (fragment != null && fragment.isVisible())return fragment;}return null;}
 三、通过接口调用实现

0 0
原创粉丝点击