Fragment生命周期之ViewPager懒加载

title: Fragment生命周期之ViewPager懒加载


Fragment生命周期

  • onCreateView() :每次加载Fragment的时候会执行该方法、配对的生命周期是: onDestroyView()

  • onViewCreated() :onCreateView()方法执行完后进行执行,代表View绘制完成

  • onResume() :该Fragment被执行了show操作、或者是该页面从后台显示到前台,或者是其依赖的Activity的生命周期的改变;那种ViewPager+Fragment的那种,ViewPager切换的时候,其Fragment是不执行onResume和onPause的,因为其Activity的声明周期没有改变,而且也没有执行hide和show操作,其移动就是将该Fragment进行了移动,并没有移出到后台?所以没有执行Fragment的生命周期、、、、、其实Fragment的生命周期都是根据Activity来的,除了自己的创建、尤其是onResume和onPause都是根据Activity的声明周期的onResume和onPause、、、、真正的判断实现的方法有两个:setUserVisibleHint()和onHiddenChanged()---针对show\hide的Fragment

picture

ViewPager+Fragment “预”加载方式解析

  • viewPager.setOffscreenPageLimit(x): 不设置默认ViewPager会预加载相邻的1个Fragment,当切换Fragment时之前相邻的Fragment会执行onDestroyView()将Fragment销毁,当再次切换到该Fragment时其会重新生成该Fragment,也就是重新调用onCreateView()方法,也就是每次点击非相邻的Tab会重新加载渲染一次Fragment

  • viewPager.setOffscreenPageLimit(n):设置值后,一般设置fragmentList-1,这样其切换Fragment的时候所有的Fragment不会重走生命周期,也就是不会走onDestroyView()和onCreateView()进行Fragment的重复创建,这种的话刚启动加载第一个Fragment的时候,其余的都会执行onCreateView()、、onCreateView()方法进行预加载,当然这种当Activity执行生命周期onPause时,所有的都会执行onPause

  • 其实ViewPager就是ViewGroup就是一个View的容器,类似于容器也就是说不管内部有多少View其都会“一次全部”加载到容器内,也就是不管现在在屏幕中的还是没有在屏幕中显示的View,其已经全部加载到该容器中了,不会因为你不在该屏幕上显示就说你没有加载到ViewGroup中,排除外来因素(手动进行ViewGroup的移出添加、或者是手动调用内部View的相关方法),勉强解释为什么setOffscreenPageLimit(n),切换Fragment的时候,不走Fragment的声明周期

ViewPager+Fragment “懒”加载方式解析

Fragment的是否显示在前台方法(onResume\onPause在上边的那种情况代表不了)

  • setUserVisibleHint(boolean isVisibleToUser): isVisibleToUser为ture表示该Fragment在前台展示,isVisibleToUser为false表示该Frament没有在前台展示(并不代表其跑到了后台,如果都是这样那么Fragment的onResume和onPause就可以判断了),在ViewPager+Fragment模式下设置了setOffscreenPageLimit(n)并且切换Tab的时候一样会改变该值

  • setUserVisibleHint: 该方法有可能会被多次回调,也就是说在判断是否显示在前台前,最好还是判断一下该View是否加载完成,然后在决定是否进行网络请求;当然为了防止每次点击都加载数据,还可以添加个别的变量isFirst来判断是否是第一次加载

  • 这种一般设置在BaseFragment中,向外部抛出abstract方法

    public abstract void fragmentIsVisible(boolean isVisibleToUser);

      @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    isViewCreated = true;
    isFirstCreate = true;
    doLazyLoad();
    }

    ..............................
        /**
    * 返回True  表示当前View是否加载到窗口、就是是否是当前窗口展示
    *
    * @param isVisibleToUser
    */
     @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        //该方法有可能会调用多次、包括有可能View还没创建就进行调用、、、防止重复加载、防止View还没创建就进行View的调用操作
        isViewVisible = true;
        doLazyLoad();
        } else {
        isViewVisible = false;
         }
      }

    ......................................

       //需要区分是否是第一次加载、防止每次切换都进行数据的调用  更新
    private void doLazyLoad() {
        if (isViewCreated && isViewVisible) {
            if (isFirstCreate) {
            fragmentIsVisible(true);
            isFirstCreate = false;
            }
        } else {
            fragmentIsVisible(false);
        }
    }

ViewPager 的进制左右滑动

  • dispatchTouchEvent(MotionEvent ev):不变还是之前的 return super.dispatchTouchEvent(ev)-支持向下分发

  • onInterceptTouchEvent(MotionEvent ev):改变return false;不进行事件拦截,进行向底部View传递

  • onTouchEvent(MotionEvent ev) :改变 return false:底部View没有响应消费的话,事件回传过来自己也不进行消费,再往外传,不进行滑动响应

picture

你可能感兴趣的:(Fragment生命周期之ViewPager懒加载)