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

前言

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

总结

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

(0)

相关推荐

  • Android之Viewpager+Fragment实现懒加载示例

    我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用.而ViewPager默认会缓存三页数据,即:Viewpager每加载一个Fragment,都会预先加载此Fragment左侧或右侧的Fragment.而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源,浪费用户流量不止,还造成卡顿,这样的结果,我们当然不会满意.那么,能不能做到当切换到这个fr

  • Android开发技巧之Fragment的懒加载

    前言 所谓懒加载,就是当fragment完全可见的时候我们再去加载数据,我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源.这样的结果,我们当然不会满意.那么,能不能做到当切换到这个fragment的时候,它才去初始化呢? 答案就在Fragment里的setUserVisibleHint这个方

  • 详解Android 在 ViewPager 中使用 Fragment 的懒加载

    我们先看一下效果: 首先,我们要知道什么是懒加载: 懒加载,就是先初始化控件,在用户可见的时候再加载数据. 为什么要懒加载? 懒加载多被使用在新闻资讯类客户端中,试想那么多的分类如果一下子都加载出来,真的是极大地消耗了系统资源.可能有人会说 ViewPager 有 viewPager.setOffscreenPageLimit() 的方法,我们传个 0 进去不就好了吗?看过源码的应该知道,即便你传了 0 进去,系统也会默认为 1 的,也就是 ViewPager 依然会加载当前页面的前后各一个 F

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

    前言 最近有时间,所以我又双叒叕推新一篇文章了,fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期.我就按照今日头条的样式做了一个懒加载功能.文章到一半会解释大家可能遇到的不加载数据了的坑,先不剧透. Fragment的生命周期回顾 github代码直通车 (本地下载) 这里是今日头条效果: 自制效果,有图有真相: 实现思路: 使用Fragment类自带方法setUserVisibleHint()判断当前fragment是否

  • Android 仿今日头条简单的刷新效果实例代码

    点击按钮,先自动进行下拉刷新,也可以手动刷新,刷新完后,最后就多一行数据.有四个选项卡. 前两天导师要求做一个给本科学生预定机房座位的app,出发点来自这里.做着做着遇到很多问题,都解决了.这个效果感觉还不错,整理一下. MainActivity package com.example.fragmentmytest; import android.content.DialogInterface; import android.graphics.Color; import android.os.B

  • Android 仿今日头条评论时键盘自动弹出的效果(推荐)

    Android 仿今日头条评论时键盘自动弹出的效果:当点击评论时,弹出对话框,同时弹出软键盘,当点击返回键时,将对话框关闭,不只是关闭软键盘. 效果图: 对这个对话框设置一个style效果: <style name="inputDialog" parent="@android:style/Theme.Holo.Light.Dialog"> <item name="android:windowBackground">@col

  • Android 多层嵌套后的 Fragment 懒加载实现示例

    多层嵌套后的 Fragment 懒加载 印象中从 Feed 流应用流行开始,Fragment 懒加载变成了一个大家都需要关注的开发知识,关于 Fragment 的懒加载,网上有很多例子,GitHub 上也有很多例子,就连我自己在一年前也写过相关的文章.但是之前的应用可能最多的是一层 Activity + ViewPager 的 UI 层次,但是随着页面越来越复杂,越来越多的应用首页一个页面外层是一个 ViewPager 内部可能还嵌套着一层 ViewPager,这是之前的懒加载就可能不那么好用了

  • Android开发之Fragment懒加载的几种方式及性能对比

    目录 1. Support时代的懒加载 2. AndrodX时代的懒加载 3. ViewPager2时代的懒加载 4. ViewPage和ViewPager2的性能对比 Android开发中ViewPager+Fragment的懒加载 TabLayout+ViewPager+Fragment是我们开发常用的组合.ViewPager的默认机制就是把全部的Fragment都加载出来,而为了保障一些用户体验,我们使用懒加载的Fragment,就是让我们再用户可见这个Fragment之后才处理业务逻辑.

  • Android仿今日头条滑动页面导航效果

    最近项目中用到了滑动页面,也就是和目前市场上很火的"今日头条"页面滑动类似,在网上找了一下,大部分都是用ViewPager来实现的,刚开始我用的是ViewPager+ViewGroup,上面的标题按钮用的是HorizontalScrollView,写完之后感觉效果比较生硬,果断换掉,发现了一个效果比较好的第三方,也就是今天的主题:PagerSlidingTabStrip.好了,下面来具体介绍一下PagerSlidingTabStrip,进行一下源码解析. 一.看一下demo的样子吧 二

  • Android仿今日头条顶部导航栏效果的实例代码

    随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候像今日头条新闻客户端要显示的内容太多,而且又想在主界面全部显示出来,所以有加了顶部导航栏. 今日头条顶部导航栏区域的主要部分是一个导航菜单.导航菜单是一组标签的集合,在新闻客户端中,每个标签标示一个新闻类别,对应下面ViewPager控件的一个分页面.当用户在ViewPager区域滑动页面时,对应的导航菜单标签也会相应的被选中,选中的标签通过一个矩形红框高亮显示,红框背

  • Android仿今日头条APP实现下拉导航选择菜单效果

    本文实例为大家分享了在Android中如何实现下拉导航选择菜单效果的全过程,供大家参考,具体内容如下 关于下拉导航选择菜单效果在新闻客户端中用的比较多,当然也可以用在其他的项目中,这样可以很方便的选择更多的菜单.我们可以让我们的应用顶部有左右滑动或进行切换的导航菜单,也可以为了增强用户体验在应用中添加这样的下拉导航选择菜单效果. 关于它的实现原理,其实也是挺简单的,就是使用PopupWindow来进行展现,在显示时控制其高度并配置以相应的动画效果.在PopupWindow中我使用GridView

  • Android优化方案之Fragment的懒加载实现代码

    一.背景 在Android应用中,ViewPager是我们不可避免使用的一个控件,因为它可以使我们在占用较少空间的同时,增强内容的丰富性,同时以其内部流淌着Google的血液,所以它几乎成了每一个App的标配控件.但是,假如ViewPager的每一个Fragment都需要通过网络拉取数据加载,而ViewPager是默认加载前两项的,所以在很容易造成网络丢包或者网络堵塞等问题,所以Fragment使用懒加载是非常有必要的. 举个栗子: 如上图所示,我们有两个大的Tab:人物和风景.而人物Tab下有

  • Android实现今日头条订阅频道效果

    本文实例为大家分享了Android仿今日头条订阅频道,供大家参考,具体内容如下 源码:Android实现今日头条订阅频道 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andro

随机推荐