项目开发中需要fragment传递数据到activity中,由于fragment是配合viewpager的,而viewpager会自动预加载上一页和下一页,导致传递到activity的数据是错乱的,然后就想到不让viewpager预加载,viewpager有一个方法viewpager.setOffscreenPageLimit(0);表示你要加载几页,添加了此方法后发现并没有什么卵用.....
- 网上大多数说法是懒加载,即让ViewPager预加载初始化UI,而具体一些数据,网络访问请求等延迟加载。这是靠Fragment里有一个setUserVisibleHint(boolean isVisibleToUser)的方法,我们可以在这个方法里做判断,当其True可见时(即切换到某一个具体Fragment)时才去加载数据,这样可以省流量。但这里并不满足我的需求,因为某一个Fragment并不会在ViewPager滑动到其相邻的Fragment时销毁。这个只可以解决部分人问题。
我们需要了解下ViewPager的预加载机制
public class ViewPager extends ViewGroup {
private static final String TAG = "ViewPager";
private static final boolean DEBUG = false;
private static final boolean USE_CACHE = false;
private static final int DEFAULT_OFFSCREEN_PAGES = 1;
private static final int MAX_SETTLE_DURATION = 600; // ms
private static final int MIN_DISTANCE_FOR_FLING = 25; // dips
private static final int DEFAULT_GUTTER_SIZE = 16; // dips
private static final int MIN_FLING_VELOCITY = 400; // dips
static final int[] LAYOUT_ATTRS = new int[] {
android.R.attr.layout_gravity
};
上面是viewpager源码 DEFAULT_OFFSCREEN_PAGES 这个变量表示默认加载几页
- 上文中我想给setOffscreenPageLimit(0)设置为0不进行预加载,为什么会没用呢?请看源码..
* <p>You should keep this limit low, especially if your pages have complex layouts.
* This setting defaults to 1.</p>
*
* @param limit How many pages will be kept offscreen in an idle state.
*/
public void setOffscreenPageLimit(int limit) {
if (limit < DEFAULT_OFFSCREEN_PAGES) {
Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "
+ DEFAULT_OFFSCREEN_PAGES);
limit = DEFAULT_OFFSCREEN_PAGES;
}
if (limit != mOffscreenPageLimit) {
mOffscreenPageLimit = limit;
populate();
}
}
我们可以看到,如果你调用该方法传进来的值小于1是无效的,会被强行的拽回1。而且DEFAULT_OFFSCREEN_PAGES 这个值是private的,子类继承ViewPager也是不可见的。
网上有第二种说法,自定义一个ViewPager,把原生ViewPager全拷过来,修改这个DEFAULT_OFFSCREEN_PAGES 值为0。这种方案没用。为什么呢?接下来就是本文的重点了。
因为现在都8.0了,版本都老高了,其实虽然每个版本都有v4包,但是这些v4包是有差异的。这就造成高版本v4包里的ViewPager,即使你Copy它,将其DEFAULT_OFFSCREEN_PAGES的值改为0,还是不起作用的,其中的逻辑变了。具体哪里变了导致无效我也没有继续研究了。
- 完美解决方案:所以关于禁止ViewPager预加载的完美解决方案就是,使用低版本v4包里的ViewPager,完全copy一份,将其中的DEFAULT_OFFSCREEN_PAGES值改为0即可。亲测 API 14 即 Android 4.0的v4包里ViewPager 有效。
直接上代码:
此处省略5000字.....
由于代码太长,下篇文章上代码
网友评论