Android仿今日头条多个fragment懒加载的实现
转载 https://www.jb51.net/article/129574.htm
转载 更新时间:2017年12月01日 14:11:25 作者:翻滚吧李博 我要评论
前言
最近有时间,所以我又双叒叕推新一篇文章了,fragment懒加载实现虽然是个小模块,但做过的人都有体会,通常并不会轻易就成功了的,让你辗转反侧,彻夜难眠,绵绵无绝期。我就按照今日头条的样式做了一个懒加载功能。文章到一半会解释大家可能遇到的不加载数据了的坑,先不剧透。
Fragment的生命周期回顾
这里是今日头条效果:
自制效果,有图有真相:
实现思路:
使用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了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。