前言
最近有时间,所以我又双菩乱黄恼铝耍fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期。我就按照今日头条的样式做了一个懒加载功能。文章到一半会解释大家可能遇到的不加载数据了的坑,先不剧透。
Fragment的生命周期回顾
github代码直通车 (本地下载)
这里是今日头条效果:
自制效果,有图有真相:
实现思路:
使用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<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()。
换上FragmentPagerAdapter后调试,调用setUserVisibleHint,isVisible为ture了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。
总结以上是内存溢出为你收集整理的Android仿今日头条多个fragment懒加载的实现全部内容,希望文章能够帮你解决Android仿今日头条多个fragment懒加载的实现所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)