欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿今日头条多个fragment懒加载的实现

程序员文章站 2022-08-03 18:47:12
前言 最近有时间,所以我又双叒叕推新一篇文章了,fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期...

前言

最近有时间,所以我又双叒叕推新一篇文章了,fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期。我就按照今日头条的样式做了一个懒加载功能。文章到一半会解释大家可能遇到的不加载数据了的坑,先不剧透。

fragment的生命周期回顾

Android仿今日头条多个fragment懒加载的实现

github代码直通车 (本地下载

这里是今日头条效果:

Android仿今日头条多个fragment懒加载的实现

自制效果,有图有真相:

Android仿今日头条多个fragment懒加载的实现

实现思路:

使用fragment类自带方法setuservisiblehint()判断当前fragment是否对用户可见,根据回调的isvisibletouser参数来进行相关的逻辑判断。重写该方法,创建变量isvisible拿到是否可见标志。

但是直接根据isvisible判断就加载数据,可能oncreateview()方法并未执行完毕,此时就会出现nullpointerexception空指针异常。所以就需要满足控件初始化完成,用户可见,才能加载数据。

Android仿今日头条多个fragment懒加载的实现

lazyloadfragment懒加载fragment实现:

public abstract class lazyloadfragment extends fragment {
 protected view rootview;
 private boolean isinitview = false;
 private boolean isvisible = false;

 @nullable
 @override
 public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) {
  rootview = inflater.inflate(setcontentview(), container, false);
  init();
  isinitview = true;
  iscanloaddata();
  return rootview;
 }

 @override
 public void setuservisiblehint(boolean isvisibletouser) {
  super.setuservisiblehint(isvisibletouser);

  //isvisibletouser这个boolean值表示:该fragment的ui 用户是否可见,获取该标志记录下来
  if(isvisibletouser){
   isvisible = true;
   iscanloaddata();
  }else{
   isvisible = false;
  }
 }

 private void iscanloaddata(){
  //所以条件是view初始化完成并且对用户可见
  if(isinitview && isvisible ){
   lazyload();

   //防止重复加载数据
   isinitview = false;
   isvisible = false;
  }
 }

 /**
  * 加载页面布局文件
  * @return
  */
 protected abstract int setcontentview();

 /**
  * 让布局中的view与fragment中的变量建立起映射
  */
 protected abstract void init();

 /**
  * 加载要显示的数据
  */
 protected abstract void lazyload();

}

子fragment加载数据:

public class pagefragment extends lazyloadfragment implements xrecyclerview.loadinglistener {
 private commonadapter<string> adapter;
 private arraylist<string> datas = new arraylist<>();
 private xrecyclerview recyclerview;
 private handler handler = new handler();

 @override
 public int setcontentview() {
  return r.layout.fragment_page;
 }


 @override
 public void init() {
  recyclerview = rootview.findviewbyid(r.id.recyclerview);
  recyclerview.setlayoutmanager(new linearlayoutmanager(getactivity()));
  adapter = new commonadapter<string>(getactivity(),r.layout.item,datas) {
   @override
   protected void convert(viewholder holder, string s, int position) {

   }
  };
  recyclerview.setadapter(adapter);
  recyclerview.setpullrefreshenabled(true);
  recyclerview.setloadinglistener(this);

 }

 @override
 public void lazyload() {
  recyclerview.refresh();
 }

 @override
 public void onrefresh() {
  handler.postdelayed(new runnable() {
   @override
   public void run() {
    recyclerview.refreshcomplete();
    for(int i=0;i<10;i++){
     datas.add("");
    }
    adapter.notifydatasetchanged();
   }
  },500);
 }

 @override
 public void onloadmore() {

 }
}

最后mainactivity代码:

public class mainactivity extends appcompatactivity {
 private tablayout tablayout;
 private string[] topics = new string[]{"推荐","热点","北京","视频","社会","图片"};
 private viewpager viewpager;
 private arraylist<fragment> fragments = new arraylist<>();

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  getwindow().addflags(windowmanager.layoutparams.flag_fullscreen);
  setcontentview(r.layout.activity_main);

  init();
 }

 private void init() {
  viewpager = (viewpager) findviewbyid(r.id.viewpager);
  tablayout = (tablayout) findviewbyid(r.id.tablayout);
  viewpager.setoffscreenpagelimit(3);

  for(int i=0;i<topics.length;i++){
   tablayout.addtab(tablayout.newtab());
   fragments.add(new pagefragment());
  }
  viewpager.setadapter(new fmpageradapter(fragments,getsupportfragmentmanager()));
  tablayout.setupwithviewpager(viewpager);

  for (int j = 0; j < topics.length; j++) {
   tablayout.gettabat(j).settext(topics[j]);
  }
 }
}

坑来了

大家千篇一律地说用setuservisiblehint()方法就可以了,但是没有说这个问题。是不是用了lazyloadfragment不加载数据了?因为你用的是viewpager用的是pageradapter,用pageradapter,打断点调试,根本就没有调用setuservisiblehint(),所以isvisible还是false,不执行lazyload方法。需要用fragmentpageradapter显示调用setuservisiblehint()。

Android仿今日头条多个fragment懒加载的实现

换上fragmentpageradapter后调试,调用setuservisiblehint,isvisible为ture了。

Android仿今日头条多个fragment懒加载的实现

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。