前言
我们使用Activity的时候,可以通过startActivityForResult
来启动一个新的Activity,然后在新的Activity中可以用setResult
来向前一个Activity回传一些结果信息,前一个Activity会在onActivityResult
中得到这个信息。
那么当我们使用Fragment的形式来作为页面的时候呢?我们知道可以使用setArguments
向后面的Fragment传递信息,但是如何回传结果信息?
setTargetFragment
Android提供了一种方式setTargetFragment
public void setTargetFragment(Fragment fragment, int requestCode) 复制代码
将前一个Fragment设置给后面的Fragment,然后就可以通过getTargetFragment()
和getTargetRequestCode()
来获取对应的Fragment和Code。
当我们需要回传信息的时候,就可以调用onActivityResult
即可,如下:
getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intentData); 复制代码
这样前一个Fragment就可以在它的onActivityResult
处理这些回传信息。
上面可以发现其实就是将前一个Fragment对象交给后面的Fragment持有而已,我们自己创建一个set函数其实也可以实现,但是还是推荐使用Android提供的setTargetFragment
,来看看它的源码:
/** * Optional target for this fragment. This may be used, for example, * if this fragment is being started by another, and when done wants to * give a result back to the first. The target set here is retained * across instances via {@link FragmentManager#putFragment * FragmentManager.putFragment()}. * * @param fragment The fragment that is the target of this one. * @param requestCode Optional request code, for convenience if you * are going to call back with {@link #onActivityResult(int, int, Intent)}. */ public void setTargetFragment(Fragment fragment, int requestCode) { // Don't allow a caller to set a target fragment in another FragmentManager, // but there's a snag: people do set target fragments before fragments get added. // We'll have the FragmentManager check that for validity when we move // the fragments to a valid state. final FragmentManager mine = getFragmentManager(); final FragmentManager theirs = fragment != null ? fragment.getFragmentManager() : null; if (mine != null && theirs != null && mine != theirs) { throw new IllegalArgumentException("Fragment " + fragment + " must share the same FragmentManager to be set as a target fragment"); } // Don't let someone create a cycle. for (Fragment check = fragment; check != null; check = check.getTargetFragment()) { if (check == this) { throw new IllegalArgumentException("Setting " + fragment + " as the target of " + this + " would create a target cycle"); } } mTarget = fragment; mTargetRequestCode = requestCode; } /** * Return the target fragment set by {@link #setTargetFragment}. */ final public Fragment getTargetFragment() { return mTarget; } /** * Return the target request code set by {@link #setTargetFragment}. */ final public int getTargetRequestCode() { return mTargetRequestCode; } 复制代码
可以看到setTargetFragment
会先进行两轮校验,首先保证前后两个Fragment是同样的FragmentManager,然后保证TargetFragment和当前Fragment不是同一个,所以setTargetFragment
会更安全,而且Android已经提供了这套方式,我们就没必要自己再实现了。