Fragment使用笔记(三)

萝らか妹 提交于 2020-08-12 13:35:21

结合Fragment + ViewPager以及Fragment + FrameLayout(add + attach + detach),整理出如下:BaseFragment

package com.jingtuo.android.app.compat.pro.fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

/**
 * Fragment-基类
 *
 * 经过分析Fragment+ViewPager的Fragment的生命周期,不建议Fragment+ViewPager嵌套Fragment+ViewPager,因为会预加载嵌套内的不可见Fragment
 *
 * @author JingTuo
 */
public class BaseFragment extends Fragment {

    private final String TAG;

    public BaseFragment() {
        TAG = getClass().getSimpleName();
    }

    private boolean userVisible = false;

    private boolean containerIsViewPager = false;

    private boolean resume = false;

    private BaseFragment parentFragment;

    private boolean show = false;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate");
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.i(TAG, "onAttach");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        containerIsViewPager = container instanceof ViewPager;
        return inflater.inflate(onCreateLayoutId(), container, false);
    }

    protected int onCreateLayoutId() {
        return -1;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.i(TAG, "onViewCreated");

    }

    @Override
    public void onAttachFragment(Fragment childFragment) {
        super.onAttachFragment(childFragment);
        //当出现Fragment嵌套Fragment时,需要额外处理
        //当前的fragment已经onResume
        //childFragment刚刚被attach,还没有没有执行onCreate、onViewCreated、onResume
        //在此处设置ParentFragment状态,在childFragment的onResume方法中拦截判断是否是真正显示
        Log.i(TAG, "onAttachFragment: " + childFragment.getClass().getSimpleName());
        if (childFragment instanceof BaseFragment) {
            ((BaseFragment) childFragment).setParentFragment(this);
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.i(TAG, "onActivityCreated");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.i(TAG, "onStart");
    }

    /**
     * Fragment + ViewPager必然触发setUserVisibleHint
     * 首次创建的Fragment
     * 显示的Fragment: setUserVisibleHint(false)->setUserVisibleHint(true)->onResume
     * 预加载的Fragment: setUserVisibleHint(false)->onResume->setUserVisibleHint(true)
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        Log.i(TAG, "setUserVisibleHint: " + isVisibleToUser);
        boolean flag = !userVisible && !isVisibleToUser || userVisible && isVisibleToUser;
        if (flag) {
            //状态未发生变化,忽略
            return;
        }
        if (parentIsShow()) {
            //没有在Fragment中或者父Fragment的容器已经显示
            if (isVisibleToUser) {
                if (resume) {
                    //resume是false时,view还没有创建不进行预加载处理
                    onShow();
                }
            } else {
                onHide();
            }
        }
        //父Fragment没有显示时,触发此方法属于预加载,预加载过程中,先setUserVisibleHint,后onResume,在onResume中触发onPreload
        userVisible = isVisibleToUser;
    }

    @Override
    public void onResume() {
        super.onResume();
        resume = true;
        Log.i(TAG, "onResume: parent show: " + parentIsShow());
        Log.i(TAG, "onResume: " + containerIsViewPager + ", " + userVisible);
        if (parentIsShow()) {
            //没有在Fragment中或者父Fragment的容器已经显示
            if (containerIsViewPager) {
                if (userVisible) {
                    //userVisible为false时,是预加载,在setUserVisibleHint处理真正的显示
                    onShow();
                } else {
                    onPreload();
                }
            } else {
                onShow();
            }
        } else {
            //父Fragment没有显示,是预加载
            onPreload();
        }
    }

    /**
     * 真正显示
     */
    public void onShow() {
        show = true;
        Log.i(TAG, "onShow");
        List<Fragment> fragments = getChildFragmentManager().getFragments();
        for (Fragment fragment: fragments) {
            if (fragment instanceof BaseFragment) {
                BaseFragment baseFragment = (BaseFragment) fragment;
                Log.i(TAG, "child fragment " + baseFragment.getClass().getSimpleName() + ": " + baseFragment.containerIsViewPager + "," + baseFragment.isUserVisible() + "," + baseFragment.isResume());
                if (baseFragment.containerIsViewPager) {
                    if (baseFragment.userVisible && baseFragment.resume) {
                        baseFragment.onShow();
                    }
                } else {
                    if (baseFragment.resume) {
                        baseFragment.onShow();
                    }
                }
            }
        }
    }

    /**
     * 真正隐藏
     */
    public void onHide() {
        show = false;
        Log.i(TAG, "onHide");
        List<Fragment> fragments = getChildFragmentManager().getFragments();
        for (Fragment fragment: fragments) {
            if (fragment instanceof BaseFragment) {
                BaseFragment baseFragment = (BaseFragment) fragment;
                Log.i(TAG, "child fragment " + baseFragment.show);
                //每次只有一个子Fragment显示,只需要将当前显示的hide即可
                if (baseFragment.show) {
                    baseFragment.onHide();
                }
            }
        }
    }

    /**
     * 预加载
     */
    public void onPreload() {
        Log.i(TAG, "onPreload");
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        Log.i(TAG, "onHiddenChanged: " + hidden);
    }

    @Override
    public void onPause() {
        super.onPause();
        resume = false;
        Log.i(TAG, "onPause");
        if (containerIsViewPager) {
            //真正隐藏地方在setUserVisibleHint(false)
        } else {
            onHide();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.i(TAG, "onStop");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.i(TAG, "onDetach");
        if (parentFragment != null) {
            parentFragment = null;
        }
    }

    public boolean isUserVisible() {
        return userVisible;
    }

    public boolean isResume() {
        return resume;
    }

    public void setParentFragment(BaseFragment parentFragment) {
        this.parentFragment = parentFragment;
    }

    /**
     * 判断父Fragment是否显示
     * @return
     */
    public boolean parentIsShow() {
        if (parentFragment == null) {
            //当没有父Fragment,认为是显示
            return true;
        }
        //判断父Fragment是否显示&&父Fragment的父Fragment是否显示
        return parentFragment.show && parentFragment.parentIsShow();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!