【转】实现ViewPager懒加载的三种方法
方法一
在Fragment可见时请求数据。此方案仍预加载了前后的页面,但是没有请求数据,只有进入到当前Framgent时才请求数据。
优点:实现了数据的懒加载
缺点:一次仍是三个Framgment对象,不是完全意义的懒加载
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class FragmentSample extends Fragment{
.......
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
requestData(); // 在此请求数据
}
}
......
}
|
方法二
直接修改ViewPager源码。通过查看ViewPager源码可知,控制其预加载的是一个常量 DEFAULT_OFFSCREEN_PAGES,其默认值为1,表示当前页面前后各预加载一个页面,在这里我们直接将其设置为0即可,即去掉预加载。但是,这样有一个问题,那就是在使用其他控件时需要传入ViewPager时,这个就不能用了。
优点:完全屏蔽掉了预加载
缺点:应用太受限制,比如使用ViewPagerIndicator时需要传入ViewPager对象,这时傻眼了。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 注意,这是直接拷贝的ViewPager的源码,只修改了注释处的代码
public class LazyViewPager extends ViewGroup {
private static final String TAG = "LazyViewPager";
private static final boolean DEBUG = false;
private static final boolean USE_CACHE = false;
// 默认为1,即前后各预加载一个页面,设置为0去掉预加载
private static final int DEFAULT_OFFSCREEN_PAGES = 0;
private static final int MAX_SETTLE_DURATION = 600; // ms
static class ItemInfo {
Object object;
int position;
boolean scrolling;
}
private static final Comparator<ItemInfo> COMPARATOR = new Comparator<ItemInfo>() {
@Override
public int compare(ItemInfo lhs, ItemInfo rhs) {
return lhs.position - rhs.position;
}
};
............
}
|
方法三
直接继承ViewPager,结合PagerAdapter实现懒加载。该方案是我用到的最完善的方法,完全的懒加载,每次只会建立一个Fragment对象。
优点:完全屏蔽预加载
缺点:稍微复杂,需要自定义,开源库地址
这个库就4个类,作者通过继承ViewPager(保证其普适性)、自定义ViewPagerAdapter和 LazyFragmentPagerAdapter以及设置懒加载的标记接口,很好的实现了懒加载。感谢作者。
在此贴出关键代码,有兴趣的同学可以学习下。
LazyViewPager:
|
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
public class LazyViewPager extends ViewPager {
private static final float DEFAULT_OFFSET = 0.5f;
private LazyPagerAdapter mLazyPagerAdapter;
private float mInitLazyItemOffset = DEFAULT_OFFSET;
public LazyViewPager(Context context) {
super(context);
}
public LazyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LazyViewPager);
setInitLazyItemOffset(a.getFloat(R.styleable.LazyViewPager_init_lazy_item_offset, DEFAULT_OFFSET));
a.recycle();
}
/**
* change the initLazyItemOffset
* @param initLazyItemOffset set mInitLazyItemOffset if {@code 0 < initLazyItemOffset <= 1}
*/
public void setInitLazyItemOffset(float initLazyItemOffset) {
if (initLazyItemOffset > 0 && initLazyItemOffset <= 1) {
mInitLazyItemOffset = initLazyItemOffset;
}
}
@Override
public void setAdapter(PagerAdapter adapter) {
super.setAdapter(adapter);
mLazyPagerAdapter = adapter != null && adapter instanceof LazyPagerAdapter ? (LazyPagerAdapter) adapter : null;
}
@Override
protected void onPageScrolled(int position, float offset, int offsetPixels) {
if (mLazyPagerAdapter != null) {
if (getCurrentItem() == position) {
int lazyPosition = position + 1;
if (offset >= mInitLazyItemOffset && mLazyPagerAdapter.isLazyItem(lazyPosition)) {
mLazyPagerAdapter.startUpdate(this);
mLazyPagerAdapter.addLazyItem(this, lazyPosition);
mLazyPagerAdapter.finishUpdate(this);
}
} else if (getCurrentItem() > position) {
int lazyPosition = position;
if (1 - offset >= mInitLazyItemOffset && mLazyPagerAdapter.isLazyItem(lazyPosition)) {
mLazyPagerAdapter.startUpdate(this);
mLazyPagerAdapter.addLazyItem(this, lazyPosition);
mLazyPagerAdapter.finishUpdate(this);
}
}
}
super.onPageScrolled(position, offset, offsetPixels);
}
}
public abstract class LazyFragmentPagerAdapter extends LazyPagerAdapter<Fragment> {
private static final String TAG = "LazyFragmentPagerAdapter";
private static final boolean DEBUG = false;
private final FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
public LazyFragmentPagerAdapter(FragmentManager fm) {
mFragmentManager = fm;
}
@Override
public void startUpdate(ViewGroup container) {
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG)
Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(container, position);
if (fragment instanceof Laziable) {
mLazyItems.put(position, fragment);
} else {
mCurTransaction.add(container.getId(), fragment, name);
}
}
if (fragment != getCurrentItem()) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG)
Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object + " v=" + ((Fragment) object).getView());
final long itemId = getItemId(position);
String name = makeFragmentName(container.getId(), itemId);
if (mFragmentManager.findFragmentByTag(name) == null) {
mCurTransaction.detach((Fragment) object);
} else {
mLazyItems.remove(position);
}
}
@Override
public Fragment addLazyItem(ViewGroup container, int position) {
Fragment fragment = mLazyItems.get(position);
if (fragment == null)
return null;
final long itemId = getItemId(position);
String name = makeFragmentName(container.getId(), itemId);
if (mFragmentManager.findFragmentByTag(name) == null) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
mCurTransaction.add(container.getId(), fragment, name);
mLazyItems.remove(position);
}
return fragment;
}
@Override
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mCurTransaction.commitAllowingStateLoss();
mCurTransaction = null;
mFragmentManager.executePendingTransactions();
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() == view;
}
public long getItemId(int position) {
return position;
}
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
/**
* mark the fragment can be added lazily
*/
public interface Laziable {
}
}
|
友情提示:填充LazyViewPager的Fragment一定要实现接口LazyFragmentPagerAdapter.Laziable,其实就是一个标记。
原文链接:
http://answerzhao.github.io/2016/06/06/%E5%AE%9E%E7%8E%B0ViewPager%E6%87%92%E5%8A%A0%E8%BD%BD%E7%9A%84%E4%B8%89%E7%A7%8D%E6%96%B9%E6%B3%95/#
其他参考地址:
http://www.jianshu.com/p/104be7cd72b6
http://www.cnblogs.com/dasusu/p/5926731.html
【转】实现ViewPager懒加载的三种方法的更多相关文章
- jquery动态加载js三种方法实例
这里为你提供了三种动态加载js的jquery实例代码哦,由于jquery是为用户提供方便的,所以利用jquery动态加载文件只要一句话$.getScript(\"test.js\" ...
- Hibernate懒加载的三种解决方案
Hibernate懒加载的两种解决方案: 1.Hibernate.initialize(代理对象) 2.在*.hbm.xml映射文件中添加lazy="false"属性 3.使用op ...
- Webpack实现路由懒加载的三种方式
原文指路:https://blog.csdn.net/qq_37540004/article/details/78727063 第一种: 引入方式(正常引入): const router = new ...
- vue+webpack 实现懒加载的三种方式
第一种: 引入方式 就是正常的路由引入方式 const router = new Router({ routes: [ { path: '/hyh', component: hyh, name: 'h ...
- vue实现懒加载的几种方法
vue实现惰性加载是基于: 1.ES6的异步机制 components: { comp: (resolve, reject) => {} } 2. webpack的代码分割功能 require. ...
- QML中文件的加载(三种方法)
在这里小小总结一下QML文件中如何加载QML文件与JavaScript文件. 1.QML文件中加载JavaScript文件 语法: import <ModuleIdentifier> &l ...
- 图片懒加载插件lazyload使用方法
图片懒加载插件lazyload使用方法 一.如何使用: Lazy Load 依赖于 jQuery.引入文件 <script type="text/javascript" sr ...
- Hibernate的懒加载session丢失解决方法
在web.xml加入spring提供的过滤器,延长session的生命周期 <!--Hibernate的懒加载session丢失解决方法 --> <filter> <fi ...
- HBase协处理器加载的三种方式
本文主要给大家罗列了HBase协处理器加载的三种方式:Shell加载(动态).Api加载(动态).配置文件加载(静态).其中静态加载方式需要重启HBase. 我们假设我们已经有一个现成的需要加载的协处 ...
随机推荐
- 使用 CoordinatorLayout 出错 inflating class android.support.design.widget.CoordinatorLayout
ava.lang.RuntimeException: Unable to start activity ComponentInfo{com.czr.ianpu/com.czr.ianpu.MainAc ...
- oracle db link的查看创建与删除
1.查看dblink select owner,object_name from dba_objects where object_type='DATABASE LINK'; 或者 select * ...
- wpf xaml文件编辑出现中文乱码
突然有一天,发现在xaml文件编辑窗里打汉字出来了乱码...抓狂 结果发现是番茄助手搞得鬼.只能在编辑xaml文件是暂时关闭番茄助手 visual assist
- Mysql触发器
触发器(trigger)作用:监视某种情况,并触发某种操作. 触发器创建语法四要素: 1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/b ...
- 测试或运维工作过程中最常用的几个linux命令?
大家在测试工作过程中,可能会遇到需要你去服务器修改一些配置文件,譬如说某个字段的值是1 则关联老版本,是0则关联新版本,这时候你可能就需要会下vi的命令操作:或者查看session设置的时长,可能需 ...
- JavaScript中的类型转换
1.隐式类型转换 ①== 如果相等操作的两个变量不是同一类型,那么相等运算符会尝试进行一些类型转换: 如果一个是null,一个是undefined,则他们相等: 如果一个值是数字,另一个是字符串,先将 ...
- git 提交空文件夹
git不能提交空文件夹 find . -type d -empty -execdir touch {}/.gitkeep \; -type -d 搜索文件夹 -empty 只搜索空文件夹 -execd ...
- BootLoader(2440)核心初始化代码
1.gboot.lds OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS { . = 0x30008000; //起始地址 . = ALIGN(4);// ...
- Caffe学习
将binaryproto转为npy import caffe % suppose caffe is already in the path of Python import numpy as np i ...
- Scanner类
Scanner类:用于获取用户的键盘输入 成员方法: public boolean hasNextXxx():判断是否某种类型的元素 public Xxx nextXxx():获取该元素 常用方法: ...