• Android如何实现向前一个Fragment回传信息的功能?
  • 发布于 2个月前
  • 276 热度
    0 评论
前言
我们使用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,来看看它的源码:
/**
 * 堆代码 duidaima.com
 * 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已经提供了这套方式,我们就没必要自己再实现了。
用户评论