ViewPager的addOnPageChangeListener和setOnPageChangeListener的区别,ViewPager改变数据后IndexOutOfBoundsException
我的ViewPager数据改变后,在切换界面刷新数据时:OnPageChangeListener中的数据IndexOutOfBoundsException,我们来看源码探一下究竟;
代码时这样写的:
vpLoveCar.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
PreferenceUtil.set("OWNERCARVIN",carList.get(position).getVin_code());//记录当前索引,下拉刷新时更新该辆车;再次进入时显示该辆车;
} @Override
public void onPageScrollStateChanged(int state) { }
});
各种使用都没有问题,但是当carList的集合长度变化时(size变大后),我再去切换就会崩溃,这个问题足足影响了一个星期,我一直以为是数据操作的问题;直到今天我看了addOnPageChangeListener的源码。。。。。。
ViewPager的addOnPageChangeListener的源码:
private List<OnPageChangeListener> mOnPageChangeListeners;
private OnPageChangeListener mOnPageChangeListener;
/**
* Add a listener that will be invoked whenever the page changes or is incrementally
* scrolled. See {@link OnPageChangeListener}.
*
* <p>Components that add a listener should take care to remove it when finished.
* Other components that take ownership of a view may call {@link #clearOnPageChangeListeners()}
* to remove all attached listeners.</p>
*
* @param listener listener to add
*/
public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
if (mOnPageChangeListeners == null) {
mOnPageChangeListeners = new ArrayList<>();
}
mOnPageChangeListeners.add(listener);
}
ViewPager的setOnPageChangeListener的源码:
/**
* Set a listener that will be invoked whenever the page changes or is incrementally
* scrolled. See {@link OnPageChangeListener}.
*
* @param listener Listener to set
*
* @deprecated Use {@link #addOnPageChangeListener(OnPageChangeListener)}
* and {@link #removeOnPageChangeListener(OnPageChangeListener)} instead.
*/
@Deprecated
public void setOnPageChangeListener(OnPageChangeListener listener) {
mOnPageChangeListener = listener;
}
由源码可知:addOnPageChangeListener这个方法,每调用一次都会添加一个OnPageChangeListener的监听,ViewPager会把这些监听存在一个List的集合中;所以我每次add一个监听,就会增加一个OnPageChangeListener,里面的数据也会有不同;会导致你有多个OnPageChangeListener,但是每个回调里面的position却是同样的,它去你集合长度小的那个里面OnPageChangeListener去获取数据,所以会下标越界异常;
源码提示让你在添加时去清空之前的OnPageChangeListener:
/**
* Remove all listeners that are notified of any changes in scroll state or position.
*/
public void clearOnPageChangeListeners() {
if (mOnPageChangeListeners != null) {
mOnPageChangeListeners.clear();
}
}
而setOnPageChangeListener这个方法,每调用一次都会新设置一个OnPageChangeListener的监听,ViewPager会替换你之前的监听; 用这个方法的话数据每次都是最新的,所以不会下表越界异常;
/**
* Remove a listener that was previously added via
* {@link #addOnPageChangeListener(OnPageChangeListener)}.
*
* @param listener listener to remove
*/
public void removeOnPageChangeListener(@NonNull OnPageChangeListener listener) {
if (mOnPageChangeListeners != null) {
mOnPageChangeListeners.remove(listener);
}
}
我最后的解决方式,有两种:
1、先清空在添加监听
vpLoveCar.clearOnPageChangeListeners();
vpLoveCar.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
PreferenceUtil.set("OWNERCARVIN",carList.get(position).getVin_code());//记录当前索引,下拉刷新时更新该辆车;再次进入时显示该辆车;
} @Override
public void onPageScrollStateChanged(int state) { }
});
2、设置监听
vpLoveCar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
PreferenceUtil.set("OWNERCARVIN",carList.get(position).getVin_code());//记录当前索引,下拉刷新时更新该辆车;再次进入时显示该辆车;
} @Override
public void onPageScrollStateChanged(int state) { }
});
收获不小,我之前在使用这些方法没有出问题的时候,我一直认为addOnPageChangeListener和setOnPageChangeListener是一样的,知道今天改变数据后会下标越界异常;多去看一下源码还是有好处的;
ViewPager的addOnPageChangeListener和setOnPageChangeListener的区别,ViewPager改变数据后IndexOutOfBoundsException的更多相关文章
- [web] Get和Post区别,EncType提交数据的格式详解
转载自:http://www.cnblogs.com/sunxucool/archive/2012/12/11/2813113.html 1. get是从服务器上获取数据,post是向服务器传送数据. ...
- Get和Post区别,EncType提交数据的格式详解——转自他人博客的
1. get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过 ...
- Kafka session.timeout.ms heartbeat.interval.ms参数的区别以及对数据存储的一些思考
Kafka session.timeout.ms heartbeat.interval.ms参数的区别以及对数据存储的一些思考 在计算机世界中经常需要与数据打交道,这也是我们戏称CURD工程师的原因之 ...
- viewpager处理(三):让viewpager不预加载下一页
有时候viewpager加载页面的时候,我们发现页面的数据量很大,预加载的话会消耗性能,为了节省用户流量和手机性能,所以我们想让viewpager不自动预加载下一页,怎么实现呢? viewpager预 ...
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
ViewPager是android-support-v4.jar包中的一个系统控件,继承自ViewGroup,专门用以实现左右滑动切换View的效果,使用时需要首先在Project->prope ...
- ViewPager部分源码分析一:加载数据
onMeasure()调用populate(),完成首次数据初始化. populate()维护ViewPager的page,包括mItems和mAdapter. populate(): if (cur ...
- viewpager处理(一):让viewpager不能滑动
1.实现原理: 自定义viewpager,重写onTouchEvent方法,什么触摸事件都不响应即可让viewpager不能滑动. 2.代码如下 public class NoScrollViewPa ...
- python2与python3的区别 ,小数据池 bytes 类型
一.python2和3的区别 在python3中 在python2中 print('ab')方式打印内容()括号是必须要有的. print 'ab' 可以加可以不加. 只有range 有ran ...
- Linux与Windows的区别(后面了解后继续更新)
1.转自知乎上的@Haoyuan Xing得答案: Linux是一个以开发者为中心的操作系统,Windows是以消费者为中心的操作系统.这是最根本的区别,也是Linux相对于Windows的优势/劣势 ...
随机推荐
- day10 内容大纲
01 去年内容回顾 01 去年内容回顾 *args **kwargs: 万能参数,动态参数 * 魔性用法: 函数的定义时,* ** 聚合. 函数的执行时,* ** 打散. 形参顺序: 位置参数,*ar ...
- virtualBox 虚拟机下nginx设置不缓存静态文件不起作用解决办法
最近开发的时候,调整js时会一直使用缓存文件,无法显示改动!nginx配置静态文件add_header Cache-Control no-cache;也不起作用,很苦恼! nginx配置代码:even ...
- java自动装箱的一个例子
Object obj = 56; int i = (Integer)obj; 第一行等价于: Object obj = Integer.valueOf(56); Integer.valueO ...
- 深入理解ASP.NET MVC(7)
系列目录 Action的定位 再次回到Controller的ExecuteCore方法,回到action调用的入口: 1 if (!ActionInvoker.InvokeAction(Control ...
- centos7 使用cgroup进行资源限制
centos7中进行资源限制,使用的仍然是cgroup,只是配置接口使用的systemd. 下文将介绍如何使用systemd进行资源限制. Step1 编写unit文件 命令为my-demo.serv ...
- Linux CentOS6升级glibc库过程
CentOS6升级glibc库过程 hadoop无法加载native库,可能原因是 glibc库版本过低,需要升级. 第一:安装以下软件 yum -y install zlib zlib-devel ...
- PHP-不同Str 拼接方法性能对比
问题 在PHP中,有多种字符串拼接的方式可供选择,共有: 1 . , .= , sprintf, vprintf, join, implode 那么,那种才是最快的,或者那种才是最适合业务使用的,需要 ...
- Azure REST API (4) 在Python环境下,使用Azure REST API
<Windows Azure Platform 系列文章目录> 之前遇到的项目中,客户需要在Python环境下,监控Azure VM的CPU利用率,在这里简单记录一下. 笔者的环境是Win ...
- Jenkins的详细安装
操作环境:Windows 一.环境准备 1 安装JDK 本文采用jdk-8u111-windows-x64.exe: 2 配置tomcat 本文采用tomcat8,无需安装,配置JAVA_HOME及J ...
- 【AMQ】之JMS概念
1.JMS(Java Message Service)Java消息服务,是Java20几种技术其中之一 2.JMS规范定义了Java中访问消息中间件的接口,但是没有给实现,这个实现就是由第三方使用者来 ...