Fragment是否可見

前言

最近做項目領(lǐng)導(dǎo)要求對網(wǎng)絡(luò)請求做優(yōu)化,盡量減少請求接口。

Fragment是否可見

對于Activity可以很輕易的通過 onStartonStop就能知道當前的頁面是否可見。fragment依賴于Activity。生命周期也是共享的。通過Activity的生命周期來判斷fragment是不準確的。fragment似乎也沒有這樣的方法。

常見的fragment使用:

  • Activity+fragment
  • Activity+ViewPager+fragment
  • fragment+fragment

判斷Fragment可見的情況

我們先思考Fragment不可見都有幾種情況:

  1. Activity 不可見,可以通過onPause()判斷。
  2. ViewPager中被滑出屏幕之外,可以通過 getUserVisibleHint() 判斷。
  3. Activity執(zhí)行hide(),可以通過 onHiddenChanged()判斷行。

除去上面三種情況,其他時候fragment認為就是可見的。

知道了不可見的情況,通過上述幾個方法手動維護一個是否可見的變量。

代碼如下:

/**
 * @project:FlycoTabLayout-master
 * @author:小卷子
 * @date 2018/7/31
 * @describe:
 * @fix:
 */
public abstract class BaseFragment extends Fragment {
    
    //不可見
    private boolean isLastVisible = false;
    //是否是第一次可見
    private boolean isFirst = true;
    //是否已經(jīng)執(zhí)行onResume
    private boolean isResuming = false;
    //view是否已經(jīng)創(chuàng)建
    private boolean isViewCreate = false;
    //是否被隱藏
    private boolean hidden = false;
    private View contentView;

    protected abstract View getContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);


    /**
     * fragment可見
     *
     * @param isFirst
     * @param isViewCreate
     */
    public abstract void onVisible(boolean isFirst, boolean isViewCreate);

    /**
     * fragment不可見
     */
    public abstract void onInvisible();

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        contentView = getContentView(inflater, container, savedInstanceState);
        isViewCreate = true;
        isLastVisible = false;
        isFirst = true;
        hidden = false;

        return contentView;
    }


    @Override
    public void onResume() {
        super.onResume();
        isResuming = true;
        //  嘗試設(shè)置可見
        trySetVisibility(true);
    }


    @Override
    public void onPause() {
        super.onPause();
        isResuming = false;
        //  嘗試設(shè)置不可見
        trySetVisibility(false);
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isViewCreate = false;
    }


    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //設(shè)置子Fragment當前可見狀態(tài)改變了
        setChildFragmentUserVisibleHint(isVisibleToUser);
    }


    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);

        setChildFragmentHiddenChanged(hidden);
    }


    /**
     * 嘗試修改可見狀態(tài)
     * 根據(jù)當前是否顯示判斷
     *
     * @param tryToShow
     */
    private void trySetVisibility(boolean tryToShow) {

        if (isLastVisible) {
            //當前可見
            if (tryToShow) {
                //嘗試顯示  當前已經(jīng)是顯示
                return;
            }

            //嘗試隱藏
            if (!isFragmentVisible()) {
                //當前已經(jīng)是不可見,回調(diào)隱藏方法
                onInvisible();
                isLastVisible = false;
            }

        } else {
            //當前不可見
            if (!tryToShow) {
                //嘗試隱藏 當前已經(jīng)是隱藏
                return;
            }

            if (isFragmentVisible()) {
                onVisible(isFirst, isViewCreate);
                isLastVisible = true;
                isFirst = false;
            }
        }

    }


    /**
     * Fragment是否可見
     *
     * @return
     */
    public boolean isFragmentVisible() {

        if (isResuming && getUserVisibleHint() && !hidden) {
            return true;
        }
        return false;
    }


    private void setChildFragmentUserVisibleHint(boolean isVisibleToUser) {
        // 嘗試設(shè)置可見狀態(tài)
        trySetVisibility(isVisibleToUser);
        if (isAdded()) {
            //已經(jīng)被添加
            // 當Fragment狀態(tài)改變,其子Fragment也狀態(tài)改變。
            List<Fragment> fragments = getChildFragmentManager().getFragments();
            if (fragments != null) {
                for (Fragment fragment : fragments) {
                    if (fragment instanceof BaseFragment) {
                        ((BaseFragment) fragment).setChildFragmentUserVisibleHint(isVisibleToUser);
                    }
                }
            }
        }
    }


    private void setChildFragmentHiddenChanged(boolean hidden) {

        this.hidden = hidden;
        trySetVisibility(!hidden);

        if (isAdded()) {
            List<Fragment> fragments = getChildFragmentManager().getFragments();
            if (fragments != null) {
                for (Fragment fragment : fragments) {
                    if (fragment instanceof BaseFragment) {
                        ((BaseFragment) fragment).setChildFragmentHiddenChanged(hidden);
                    }
                }
            }
        }

    }


}

相關(guān)資料:

Fragment懶加載(支持嵌套) 友盟統(tǒng)計Fragment時長最佳實踐

判斷Fragment是否對用戶可見

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容