美文网首页
Fragment在ViewPager里面的可见、隐藏

Fragment在ViewPager里面的可见、隐藏

作者: 紫阚 | 来源:发表于2018-07-04 16:23 被阅读34次

    需求

    在操作ViewPager时,需要知道Fragment对用户展示、隐藏的时刻。

    背景

    因为ViewPager通过 setOffscreenPageLimit提供预加载的功能,所以传统生命周期的onResume()onPause()不能准确的表达Fragment对用户是否可见。
    传统的做法是给ViewPageronPageSelect()事件里,发送一个广播,通知Fragment当前页发生了变化。Fragment对比自身position和广播携带的参数position是否一致,判断自己是否当前页,以此来执行 展示、隐藏操作。

    优化

    Fragment的生命周期里,提供了一个setUserVisibleHint(boolean isVisibleToUser)函数。它的作用是告诉系统Fragment是否对用户可见,使用场景是在ViewPager的适配器FragmentStatePagerAdapterFragmentStatePagerAdapter
    我们看下引用这个函数的地方

    1. 实例化Fragment
     @Override
        public Object instantiateItem(ViewGroup container, int position) {
      
           //....创建Fragment操作....
    
            if (fragment != mCurrentPrimaryItem) {
            //....其他操作....
            //不是当前页,则设置hint为flase
                fragment.setUserVisibleHint(false);
            }
            return fragment;
        }
    
    1. 设置Fragment为当前项
      public void setPrimaryItem(ViewGroup container, int position, Object object) {
            Fragment fragment = (Fragment)object;
            if (fragment != mCurrentPrimaryItem) {
                if (mCurrentPrimaryItem != null) {
                     //....其他操作....
                    //老的设置为不可见
                    mCurrentPrimaryItem.setUserVisibleHint(false);
                }
                if (fragment != null) {
                  //....其他操作....
                   //新的设置为可见
                    fragment.setUserVisibleHint(true);
                }
                mCurrentPrimaryItem = fragment;
            }
        }
    

    需要注意的是,setUserVisibleHint()Fragment的生命周期是没关联的的。

    互相独立

    setUserVisibleHint,在ViewPager左右滑动的时候,因为预加载的机制,所以页面已经初始化好;
    但是通过setCurrentItem(页码);跳到某个页面时,此时页面还未初始化。

    我们业务里面的操作,需要页面布局已经完成,因此在使用它的时候,我们需要额外的技巧,下面修改后的XLBaseFragment
    子类重写 showToUserInViewPagerhideToUserInViewPager()即可

        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
    
            //状态如果一致,则不去做操作
            if (mIsShowToUser == isVisibleToUser) return;
    
            //从隐藏切到显示
            if (isVisibleToUser) {
                if (mIsViewInitial) {
                    showToUserInViewPager();
                    mRemainShowEventToTake = false;
                } else {
                    mRemainShowEventToTake = true;
                }
            } else {
                //从显示切到隐藏
                hideToUserInViewPager();
            }
            mIsShowToUser = isVisibleToUser;
        }
    
      @Override
        public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
           //一些操作。。
    
            if (mRemainShowEventToTake && getUserVisibleHint()) {
                mRemainShowEventToTake = false;
                showToUserInViewPager();
            }
    
        }
    

    相关文章

      网友评论

          本文标题:Fragment在ViewPager里面的可见、隐藏

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