使用ViewPager细节:
1. viewpager做自动循环和跳转时,最好被一个对象调用,避免重复使用出问题。
2. 即使viewpager被隐藏了,但如果有事件触发,viewpager还是会执行相应的触发事件;一般情况下,我们隐藏了控件而触发不了事件是因为我们没有机会通过控件来触发事件,但如果有第三方的对象来触发控件的事件,控件同样也会执行触发事件。
3. 在dialog中加入viewpager时,viewpager在设配器的getCount()方法中的返回值不能取整型最大值Integer.MAX_VALUE,否则在退出dialog或重新执行dialog时,虚拟机容易被爆掉。需要设置小一点的值,避免内存溢出。
4. viewpager有页面选择监听事件,但没有页面的点击事件,不过可以在viewpager适配器的实例方法中给页面中的控件对象设置点击监听事件
5. viewpager的id一般是固定的,如:android:id="@+id/viewpager";另外测试还可定义id为:android:id="@+id/aViewpager" (只有a开头开可以) 和android:id="@+id/Viewpager"
6. viewpager页数是1,2,3时,不要实现循环效果,因为在左滑和滑到头时都会报错,在大于4张页面时才实现循环效果
7. ViewPager使用标签必须写:<android.support.v4.view.Viewpager
8. 设置适配器是线程阻塞的,但耗时比较短
9.关于最左最右VP子view数量问题,最小-1和最大+1,当前item都不会超过最小和最大的值,只会等于
int currentItemPage = vp_page.getCurrentItem();
if (v == tv_left) {
vp_page.setCurrentItem(currentItemPage - 1);
if (currentItemPage == 0) {
ToastUtil.show("已经是第一页了");
}
}
if (v == tv_right) {
vp_page.setCurrentItem(currentItemPage + 1);
//注意:VP ChildCount 只会左中右最多3个,在最左和最右ChildCount=2
if (currentItemPage == vp_page.getChildCount()+1) {
ToastUtil.show("已经是最后一页了");
}
}
ViewPager加载view时内存溢出问题:
初始化View时,在for循环里只将ImageView对象添加到List<View>中,这里不对ImageView对象设置图片资源,将该步骤延迟到PagerAdapter$instantiateItem()中再进行设置。因为在for循环时就对ImageView设置图片资源,底层会调用BitmapFactory.decodeResource进行解码,而这个过程是耗时的,也很容易造成OOM
ViewPager加载页面小结:
1. 设置页面切换有平滑效果: sub_viewpager.setCurrentItem(0,true);
2. 设置页面切换没有平滑效果:sub_viewpager.setCurrentItem(0,false);
默认平滑效果:sub_viewpager.setCurrentItem(0);
另:
1. ViewPager加载当前页面时,默认也会加载左右两边页面,左右两边页面的内容会被执行,其他页面待加载
2. ViewPager的使用无论是在xml中还是在代码中写,记得一定要给id,不然报空异常
3. ViewPager不是一次性加载完所有view,只会加载临近的view,涉及到数据的加载需要特别注意,可以通过设置缓存页面来解决
ViewPager常用属性:
1. 设置页面之间的间距:
viewPager.setPageMargin(20);
2. ViewPager更新数据问题:(适合仅有简单控件的情况,如TextView、ImageView,不适合ListView的刷新,系统开销大)
直接使用notifyDataSetChanged是无法更新,需要同时重写getItemPosition返回常量 POSITION_NONE (此常量为viewpager带的)
@Override
public int getItemPosition(Object object) {
//表示所有child view都不存在,viewpager调用destroyItem方法销毁并重新生成
return POSITION_NONE;
}