Android fragment懒加载

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

转载  https://www.jb51.net/article/129574.htm

转载  更新时间:2017年12月01日 14:11:25   作者:翻滚吧李博    我要评论

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,下面这篇文章主要给大家介绍了关于利用Android仿今日头条多个fragment懒加载的相关资料,需要的朋友可以参考下。

前言

最近有时间,所以我又双叒叕推新一篇文章了,fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期。我就按照今日头条的样式做了一个懒加载功能。文章到一半会解释大家可能遇到的不加载数据了的坑,先不剧透。

Fragment的生命周期回顾

github代码直通车 (本地下载

这里是今日头条效果:


自制效果,有图有真相:


实现思路:

使用Fragment类自带方法setUserVisibleHint()判断当前fragment是否对用户可见,根据回调的isVisibleToUser参数来进行相关的逻辑判断。重写该方法,创建变量isVisible拿到是否可见标志。

但是直接根据isVisible判断就加载数据,可能onCreateView()方法并未执行完毕,此时就会出现NullPointerException空指针异常。所以就需要满足控件初始化完成,用户可见,才能加载数据。


LazyloadFragment懒加载fragment实现:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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加载数据:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值