美文网首页
Android---Fragment的“懒加载“

Android---Fragment的“懒加载“

作者: HPD_黄霹雳 | 来源:发表于2018-02-02 11:36 被阅读0次

    基本APP都有个首页,如:


    图片.png

    实现的方式就是底部的几个tab和一个ViewPager,ViewPager中装在Fragment
    。基本上,Fragment都会去请求数据。但是如图有4个Fragment,对应的网络请求都要去加载。这样子请求次数就大了很多。我们可以通过Fragment的“懒加载”
    来减少请求次数,只在Fragment显示的加载数据。

    我们可以通过Fragment的setUserVisibleHint方法控制

    先看下上图的关键代码:

        ArrayList<Fragment> fragments = new ArrayList<>();
            TestFragment e = new TestFragment();
            e.TAG = "dfasdfdsafas TestFragment1";
            fragments.add(e);
            TestFragment e1 = new TestFragment();
            e1.TAG = "dfasdfdsafas TestFragment2";
            fragments.add(e1);
            TestFragment e2 = new TestFragment();
            e2.TAG = "dfasdfdsafas TestFragment3";
            fragments.add(e2);
            TestFragment e3 = new TestFragment();
            e3.TAG = "dfasdfdsafas TestFragment4";
            fragments.add(e3);
    
            CommonPagerAdapter commonPagerAdapter = new CommonPagerAdapter(getSupportFragmentManager(), fragments);
            activityMainViewPager.setAdapter(commonPagerAdapter);
            activityMainViewPager.setOffscreenPageLimit(4);
            activityMainViewPager.setCurrentItem(0);
    

    activityMainViewPager.setOffscreenPageLimit(4);是为了保持各个tab的页面不被销毁。

    再看下TestFragment的代码

    public class TestFragment extends Fragment {
    
        public String TAG = "dfasdfdsafas";
    
        public TestFragment() {
            // Required empty public constructor
        }
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            Log.i(TAG, "setUserVisibleHint=" + isVisibleToUser);
    
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            Log.i(TAG, "onAttach");
    
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.i(TAG, "onCreate");
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            Log.i(TAG, "onCreateView");
            return inflater.inflate(R.layout.fragment_test, container, false);
        }
    
        @Override
        public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            Log.i(TAG, "onViewCreated");
        }
    
        @Override
        public void onStart() {
            super.onStart();
            Log.i(TAG, "onStart");
        }
    
        @Override
        public void onResume() {
            super.onResume();
            Log.i(TAG, "onResume");
        }
    
        @Override
        public void onPause() {
            super.onPause();
            Log.i(TAG, "onPause");
        }
    
        @Override
        public void onStop() {
            super.onStop();
            Log.i(TAG, "onStop");
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            Log.i(TAG, "onDestroyView");
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i(TAG, "onDestroy");
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
            Log.i(TAG, "onDetach");
        }
    }
    

    App启动后,我们来看看Log

    I/dfasdfdsafas TestFragment1: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment2: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment3: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment4: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment1: setUserVisibleHint=true
    I/dfasdfdsafas TestFragment1: onAttach
    I/dfasdfdsafas TestFragment1: onCreate
    I/dfasdfdsafas TestFragment2: onAttach
    I/dfasdfdsafas TestFragment2: onCreate
    I/dfasdfdsafas TestFragment3: onAttach
    I/dfasdfdsafas TestFragment3: onCreate
    I/dfasdfdsafas TestFragment4: onAttach
    I/dfasdfdsafas TestFragment4: onCreate
    I/dfasdfdsafas TestFragment1: onCreateView
    I/dfasdfdsafas TestFragment1: onViewCreated
    I/dfasdfdsafas TestFragment1: onStart
    I/dfasdfdsafas TestFragment1: onResume
    I/dfasdfdsafas TestFragment2: onCreateView
    I/dfasdfdsafas TestFragment2: onViewCreated
    I/dfasdfdsafas TestFragment3: onCreateView
    I/dfasdfdsafas TestFragment3: onViewCreated
    I/dfasdfdsafas TestFragment4: onCreateView
    I/dfasdfdsafas TestFragment4: onViewCreated
    I/dfasdfdsafas TestFragment2: onStart
    I/dfasdfdsafas TestFragment2: onResume
    I/dfasdfdsafas TestFragment3: onStart
    I/dfasdfdsafas TestFragment3: onResume
    I/dfasdfdsafas TestFragment4: onStart
    I/dfasdfdsafas TestFragment4: onResume
    

    切换到tab2的Log

    I/dfasdfdsafas TestFragment1: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment2: setUserVisibleHint=true
    
    

    切换到tab3的log

    I/dfasdfdsafas TestFragment2: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment3: setUserVisibleHint=true
    
    

    切换到tab4的log

    I/dfasdfdsafas TestFragment3: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment4: setUserVisibleHint=true
    
    

    切换到tab1的log

    I/dfasdfdsafas TestFragment4: setUserVisibleHint=false
    I/dfasdfdsafas TestFragment1: setUserVisibleHint=true
    
    

    所以,我们可以通过setUserVisibleHint来实现”懒加载“。可以设置一个flag,来记录是否加载过数据。如:

    //用于懒加载,判断是否加载过
        protected boolean isLazyFragmentLoad = false;
    

    然后Fragment的关键代码是大概是这样子的

       @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            initData(isVisibleToUser);
        }
    
        private void initData(boolean isVisibleToUser) {
            if (!isLazyFragmentLoad && isVisibleToUser) {
                isLazyFragmentLoad = true;
               //这边加载数据
            }
        }
    

    发现setUserVisibleHint是优先于Fragment的任何的生命周期。

    这边要注意的是,ViewPgaer的第一个页面,在setUserVisibleHint里不能加载数据,因为控件啥的还没有加载好。
    解决方法:

    1. ViewPager的第一个页面不用setUserVisibleHint方法,走正常流程。

    相关文章

      网友评论

          本文标题:Android---Fragment的“懒加载“

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