Fragment是否可见

前言

最近做项目领导要求对网络请求做优化,尽量减少请求接口。

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执行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;
    //是否已经执行onResume
    private boolean isResuming = false;
    //view是否已经创建
    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;
        //  尝试设置可见
        trySetVisibility(true);
    }


    @Override
    public void onPause() {
        super.onPause();
        isResuming = false;
        //  尝试设置不可见
        trySetVisibility(false);
    }


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


    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //设置子Fragment当前可见状态改变了
        setChildFragmentUserVisibleHint(isVisibleToUser);
    }


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

        setChildFragmentHiddenChanged(hidden);
    }


    /**
     * 尝试修改可见状态
     * 根据当前是否显示判断
     *
     * @param tryToShow
     */
    private void trySetVisibility(boolean tryToShow) {

        if (isLastVisible) {
            //当前可见
            if (tryToShow) {
                //尝试显示  当前已经是显示
                return;
            }

            //尝试隐藏
            if (!isFragmentVisible()) {
                //当前已经是不可见,回调隐藏方法
                onInvisible();
                isLastVisible = false;
            }

        } else {
            //当前不可见
            if (!tryToShow) {
                //尝试隐藏 当前已经是隐藏
                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) {
        // 尝试设置可见状态
        trySetVisibility(isVisibleToUser);
        if (isAdded()) {
            //已经被添加
            // 当Fragment状态改变,其子Fragment也状态改变。
            List 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 fragments = getChildFragmentManager().getFragments();
            if (fragments != null) {
                for (Fragment fragment : fragments) {
                    if (fragment instanceof BaseFragment) {
                        ((BaseFragment) fragment).setChildFragmentHiddenChanged(hidden);
                    }
                }
            }
        }

    }


}

相关资料:

Fragment懒加载(支持嵌套) 友盟统计Fragment时长最佳实践

判断Fragment是否对用户可见

你可能感兴趣的:(Fragment是否可见)