温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2020-10-01 14:45:47 来源:脚本之家 阅读:257 作者:翻滚吧李博 栏目:移动开发

前言

最近有时间,所以我又双叒叕推新一篇文章了,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懒加载的实现

总结

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI