使用Fragment的懒加载延迟加载数据

1.什么是懒加载

懒加载是指按需/延迟加载,例如App中的资讯展示界面(一般会使用ViewPager+Fragment实现),常常会包含多个主题,考虑到节省用户流量/加快响应速度/减小服务器并发压力等等因素,一般会要求当切换至某一主题时才加载该主题对应的数据。
而ViewPager默认会保存当前页左右两边任意一侧一页的界面(通过ViewPager的setOffscreenPageLimit(int limit)方法设置,默认最小值为1),因此进入资讯界面时至少会初始化两个Fragment,与功能要求不符,这时就需要用到Fragment的懒加载技术

2.如何实现懒加载

查询资料可知,通过Fragment的setUserVisibleHint(boolean isVisibleToUser)方法可以判断当前fragment是否对用户可见,当isVisibleToUser为true时,加载数据,否则不加载数据。该方法的注释中还有一段提示:

* 

Note: This method may be called outside of the fragment lifecycle. * and thus has no ordering guarantees with regard to fragment lifecycle method calls.

翻译一下,该方法或许会在Fragment的生命周期之外被调用,因此对于Fragment生命周期方法调用没有顺序保证,即调用该方法时,可能还没有执行Fragment的onCreateView()方法,如果此时执行加载数据操作,可能引起空指针异常,因此还需要在onCreateView()方法中进行一次判断。
另外还需要注意一点,setUserVisibleHint(boolean isVisibleToUser)方法在FragmentPagerAdapter和FragmentStatePagerAdapter中被调用,因此如果需要实现懒加载,ViewPager使用的Adapter必须是这两个Adapter的子类。


使用Fragment的懒加载延迟加载数据_第1张图片
查找setUserVisibleHint()调用结果.png

3.代码示例

3.1覆写setUserVisibleHint方法

    /**
     * Fragment是否对用户可见,可见时才加载数据
     */
    private boolean isUIVisiable = false;
    /**
     * setUserVisibleHint有可能在onCreateView之前调用,故需确保View已创建后再加载数据
     */
    private boolean isViewCreated = false;

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        Log.e(TAG, "isVisibleToUser " + isVisibleToUser);
        if (isVisibleToUser) {
            isUIVisiable = true;
            //ViewPager会缓存至少相邻一页Fragment,当切换Fragment时,会调用setUserVisibleHint方法
            //这里再次触发懒加载
            lazyLoad();
        } else {
            isUIVisiable = false;
        }
    }

3.2覆写onCreateView方法

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_simple, container, false);
        ...

        isViewCreated = true;
        lazyLoad();
        return binding.getRoot();
    }

3.3添加lazyLoad方法

    private void lazyLoad() {
        Log.e(TAG, "isUIVisiable " + isUIVisiable + " isViewCreated " + isViewCreated);
        if (isUIVisiable && isViewCreated) {
            isUIVisiable = false;
            isViewCreated = false;
            getData();
        }
    }

在getData()方法中执行具体数据加载逻辑

3.4新建Adapter

    private class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {

        private List mListFragment;

        public SimpleFragmentPagerAdapter(FragmentManager fm, List fragmentList) {
            super(fm);
            mListFragment = fragmentList;
        }

        @Override
        public Fragment getItem(int position) {
            return mListFragment.get(position);
        }

        @Override
        public int getCount() {
            return mListFragment == null ? 0 : mListFragment.size();
        }
    }

3.5在Activity中使用

    private void initViewPager() {
        List fragmentList = new ArrayList<>();
        fragmentList.add(LazyLoadFragment.newInstance(ContextCompat.getColor(this, R.color.colorPrimaryDark)));
        fragmentList.add(LazyLoadFragment.newInstance(ContextCompat.getColor(this, R.color.color_86d0ab)));
        fragmentList.add(LazyLoadFragment.newInstance(ContextCompat.getColor(this, R.color.color_fb9b10)));
        fragmentList.add(LazyLoadFragment.newInstance(ContextCompat.getColor(this, R.color.colorAccent)));
        binding.viewPager.setOffscreenPageLimit(3);
        SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), fragmentList);
        binding.viewPager.setAdapter(adapter);
    }

4.实际效果

使用Fragment的懒加载延迟加载数据_第2张图片
懒加载效果图.gif

你可能感兴趣的:(使用Fragment的懒加载延迟加载数据)