当前位置:主页 > 移动开发 > Android代码 >

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

时间:2021-07-17 08:10:37 | 栏目:Android代码 | 点击:

前言

最近有时间,所以我又双????推新一篇文章了,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了。

总结

您可能感兴趣的文章:

相关文章