Fragment是否可见

作者: 傲娇的狗蛋 | 来源:发表于2018-07-31 18:03 被阅读56次

    前言

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

    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<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);
                        }
                    }
                }
            }
    
        }
    
    
    }
    

    相关资料:

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

    判断Fragment是否对用户可见

    相关文章

      网友评论

        本文标题:Fragment是否可见

        本文链接:https://www.haomeiwen.com/subject/ponhvftx.html