天天看点

快速读懂 Fragment 与 Activity 的关系

文章目录

    • FragmentActivity
    • FragmentController
    • FragmentContainer
    • FragmentHostCallback
    • FragmentManager
    • FragmentTransaction
    • 总结

FragmentActivity

继承自

Activity

,支持 support.v4

Fragment

的使用,目前已成为 Android 默认

Activity

onCreate()

中进行关联

FragmentController

相关。

protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);
				/*** 省略不重要源码 ***/
        mFragments.dispatchCreate();
    }
           

onDestroy()

中进行去关联

FragmentController

相关。

protected void onDestroy() {
        super.onDestroy();

        doReallyStop(false);

        mFragments.dispatchDestroy();
        mFragments.doLoaderDestroy();
    }
           

FragmentController

构造方法:

private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }
           

作为

FragmentActivity

的成员变量被初始化。

工厂函数

createContoller(FragmentHostCallback)

需要传入一个

FragmentHostCallback

对象,这里直接 new 了一个

HostCallbacks

,是前者的实现类。

在 Activity#onCreate()中被调用

attchHost

方法,该方法中实现了 FragmentManager 和 FragmentHostCallback 的关联。

/**
     * Attaches the host to the FragmentManager for this controller. The host must be
     * attached before the FragmentManager can be used to manage Fragments.
     */
    public void attachHost(Fragment parent) {
        mHost.mFragmentManager.attachController(
                mHost, mHost /*container*/, parent);
    }
           

FragmentContainer

抽象类,用于管理布局 view。主要实现类为

FragmentHostCallback

/**
 * Callbacks to a {@link Fragment}'s container.
 */
public abstract class FragmentContainer {
    /**
     * Return the view with the given resource ID. May return {@code null} if the
     * view is not a child of this container.
     */
    @Nullable
    public abstract View onFindViewById(@IdRes int id);

    /**
     * Return {@code true} if the container holds any view.
     */
    public abstract boolean onHasView();
}
           

FragmentHostCallback

继承自

FragmentContainer

,作为

FragmentController

的成员变量在其构造方法中被赋值,主要实现类为

HostCallbacks

/**
     * Returns a {@link FragmentController}.
     */
    public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
        return new FragmentController(callbacks);
    }

    private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }
           

FragmentManager

抽象类,作为

FragmentHostCallback

的成员变量被初始化。主要实现类为

FragmentManagerImpl

attachController()

方法中与

FragmentHostCallback

FragmentContainer

进行关联。由于 FragmentHostCallback 继承自 FragmentContainer,其实也就是一个对象,只是表现为不同的子类。

public void attachController(FragmentHostCallback host,
            FragmentContainer container, Fragment parent) {
        if (mHost != null) throw new IllegalStateException("Already attached");
        mHost = host;
        mContainer = container;
        mParent = parent;
    }
           

FragmentTransaction

抽象类,帮助

FragmentManager

管理 Fragment 的添加、移除、显示、隐藏等操作。主要实现类为

BackStackRecord

这个类应该很熟悉了,在每次执行 Fragment 的相关操作时都需要通过 FragmentManager 来获取该对象最终完成操作。例如:

val fragment = MyFragment()
                fragmentManager
                        .beginTransaction()
                        .add(rxPermissionsFragment, TAG)
                        .commitNowAllowingStateLoss()
           

这里的

beginTransaction()

每次会重新初始化一个 FragmentTransation 对象:

public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }
           

总结

大致的包含关系如下:

Activity(FragmentActivity) --> FragmentController --> FragmentContainer(FragmentHostCallback(HostCallbacks)) --> FragmentManager --> FragmentTransaction(BackStackRecord)