美文网首页ViewPagerAndroid开发
ViewPager和TabLayout取消预加载

ViewPager和TabLayout取消预加载

作者: 欢乐的乐 | 来源:发表于2017-05-26 11:06 被阅读2598次

    ╮(╯▽╰)╭写了这么多篇Android的文章都没人看,估计也因为自己写的文章都比较皮毛。
    其实每一次遇到问题第一时间都是来简书搜,简书没有再百度。一直都觉得简书里的大神写的会比较用心,像RxJava和Picasso都是在简书找到的文章学会的。
    因为这篇文章在简书还没完善的解决方案,于是我简化的大神的思路,在此献丑了。

    最终效果:(即将显示的Fragment是还没加载的,如何实现呢)

    wuli大网易云

    实现思路:

    Android中ViewPager和TabLayout组合使用真的是太方便了,一开始因为它预加载附近的页面解决了很久都没实现,差点就不想用它了。不过现在发现,它还是很有爱的。

    在ViewPager中有一个方法:
    setOffscreenPageLimit(int limit),这是预告加载的页面数量,默认是1,就算设置0了,还是会默认改成1。(这个没关系,这个反而方便了我们,接下来的工作)
    假如页面的tab数量是4个,像网易云一样,当4个页面都加载过后,除非下拉更新,否则无论页面间怎么切换数据都不会变。这时候我们就viewpager.setOffscreenPageLimit(4);

    1. 让TabFragment页面onCreateView不做任何加载数据操作

    既然setOffscreenPageLimit是不能指望取消预加载,那我们就直接放弃它了,同时也让onCreateView不做加载数据操作。

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        return view;
    }
    
    2.在使用ViewPager的页面中声明一些属性,和根据滑动的position加载数据

    本文在AlarmFragment中使用了ViewPager和TabLayout

    public int totalTabNum = 4;//假如有四个Fragment页面
    public int openTabNum = 0;//当前已打开的页面数量
    
    public void setupViewPager(){
        if(fragmentList != null && titleList != null){
            fragmentPagerAdapter = new MyFragmentPagerAdapter(getChildFragmentManager(), fragmentList, titleList);
            viewpager.setAdapter(fragmentPagerAdapter);
            tablayout.setupWithViewPager(viewpager);
            viewpager.setCurrentItem(0);
            viewpager.setOffscreenPageLimit(4);
            viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                }
    
                @Override
                public void onPageSelected(int position) {
                    //滑动监听加载数据,一次只加载一个标签页
                    if(openTabNum < totalTabNum){
                        ((TabFragment)fragmentPagerAdapter.getItem(position)).sendMessage();
                    }
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
        }
    }
    
    3. 回到TabFragment中,让Handler加载数据
    private AlarmFragment alarmFragment;//这是使用ViewPager的页面
    
    private boolean is_load = false;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(!is_load){
                is_load = true;
                if(alarmFragment.openTabNum < alarmFragment.totalTabNum){
                    alarmFragment.openTabNum++;
                }
                loadDataList();//加载网络数据的方法
            }
            return ;
        }
    };
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        this.alarmFragment = (AlarmFragment)getParentFragment();//因为这里是Fragment嵌套Fragment于是是getParentFragment
        return view;
    }
    
    public void sendMessage(){
        Message message = handler.obtainMessage();
        message.sendToTarget();
    }
    
    4. 优点

    这样做的好处就是,无论用户是一个Tab一个Tab的滑动,还是直接从Tab1跳到Tab4都是可以统计当前打开的Tab的数量,而且附近的Tab是不会被加载的。彻底像网易云的TabLayout功能一样。
    是从参考资料中的例子获取的idea,不过发现他的例子只适用于一个Tab一个Tab的滑动,假如Tab跨越的幅度大了,应该会有一点问题吧,同时逻辑也比较复杂,还是跟感谢大神的贡献,才发现Handler又可以这样用,哈哈。


    参考资料:(感谢大神的贡献)

    Android标签页TabLayout控件实战及ViewPager取消预加载


    好好学习,天天向上。<( ̄oo, ̄)/


    Potato_zero.jpg

    相关文章

      网友评论

      • 茶And狗狗:为什么sendMessage()方法里要通过handler转发一次?直接在sendMessage()中调用```if(!is_load){
        is_load = true;
        if(alarmFragment.openTabNum < alarmFragment.totalTabNum){
        alarmFragment.openTabNum++;
        }
        loadDataList();//加载网络数据的方法
        }```不就好了吗?
      • 81a27b7ab56f:tablayout与viewPager 有预加载的问题就会连续请求网路,将请求网络部分放在onResume()呢,可以试试
      • Dora_Liang:大兄弟,你贴的代码有个问题,就是当没有滑动,加载第一页的时候,没有数据,你要在判断是刚开始第一页的时候,就发送message。谢谢,总觉得还有更好的方法
        欢乐的乐:第一个是默认加载的,onPageSelected会执行,所以message也会发送:stuck_out_tongue_winking_eye:
        那时候实现了,后来项目没使用也有点遗忘了。很开心有人仔细看了一遍:yum:
      • zbiext:Demo 代码能看看吗

      本文标题:ViewPager和TabLayout取消预加载

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