前言
最近有时间,所以我又双叒叕推新一篇文章了,fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期。我就按照今日头条的样式做了一个懒加载功能。文章到一半会解释大家可能遇到的不加载数据了的坑,先不剧透。
fragment的生命周期回顾
这里是今日头条效果:
自制效果,有图有真相:
实现思路:
使用fragment类自带方法setuservisiblehint()判断当前fragment是否对用户可见,根据回调的isvisibletouser参数来进行相关的逻辑判断。重写该方法,创建变量isvisible拿到是否可见标志。
但是直接根据isvisible判断就加载数据,可能oncreateview()方法并未执行完毕,此时就会出现nullpointerexception空指针异常。所以就需要满足控件初始化完成,用户可见,才能加载数据。
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 adapter;
private arraylist 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(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 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
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()。
换上fragmentpageradapter后调试,调用setuservisiblehint,isvisible为ture了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对萬仟网的支持。