Android ListView IndexOutOfBoundsException ViewHolder类型转化错误
2016-05-21 22:37
351 查看
问题一:
我们都知道,在用Listview展示多个类型的Type时候,适配器中需要重写getItemViewType(int position)类型和getViewTypeCount()类型总数,如图:
![](https://img-blog.csdn.net/20160521221823373?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
.
![](https://img-blog.csdn.net/20160521221846920?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
但是前几天在做listview展示多个类型的时候,出现了一个错误IndexOutOfBoundsException
找了好久就是不知道怎么回事,经过一天的艰难探索,终于找到了突破点。查看源码发现类型的position必须从0开始,如图
![](https://img-blog.csdn.net/20160521221939373?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
我的需求是reply == null加载一个布局,reply != null加载另一个布局,本以为getItemViewType(position);中的position可以随便写一个整数,结果导致了这个错误。
发现错误就要解决错误,只需要把getItemViewType(position)中的position修改为从0开始。即int posi = 0;这个错误完美解决。。
问题二:
但是接着运行程序之后又报了类型转化错误java.lang.ClassCastException: com.xingtong.qiaoyuer.adapter.v_1_1.SalonTalkAdapter$ViewHolder2 cannot be cast to com.xingtong.qiaoyuer.adapter.v_1_1.SalonTalkAdapter$ViewHolder1
大概意思就是ViewHolder2不能转化为ViewHolder1,原因就是数据源开始只有type==0类型的数据,所以这时候convertView已经被实例化了,convertView已经不为null了,但是我在listview上拉加载更多数据的时候,又会加载出第二个Type的即 type==1的数据源,此时再次执行到convertView的时候发现,convertView已经不为null了,就会直接从getTag()=ViewHolder2中取出ViewHolder2中的控件值,其实理论上应该走的是TYpe
==1,ConvertView==null 那么从新实例化ConvertView ,然后convertView.setTag(ViewHolder1);理想状态下应该是发现Type==1时,发现type==1的converView没有实例化,则先实例化,发现type
==0的convertView没有实例化,则先实例化。怎样才能做到一个type类型对应一个convertView呢?就是要在数据源的时候设置上Type的类型。如图2
![](https://img-blog.csdn.net/20160521222210484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
(要是服务器返回的数据源带有类型就好了,就不用自己把list中的每一个对象都拿出来加上type然后再放进去了)。
其实在适配器Adapter执行的过程中先执行的getItemViewType(int position)方法和getViewTypeCount()类型总数方法,然后才走的getView()方法,所以形成了数据源的type一一对应的关系后,当它拿到一个bean对象的数据后发现Type和上一个bean对象的数据不一致,它就会重新初始化ConvertView,从新setTag(ViewHolder)。以此类推以后再遇到有相同类型的就直接拿以前的ViewHolder,如果没有就从新再次初始化ConvertView。
我们都知道,在用Listview展示多个类型的Type时候,适配器中需要重写getItemViewType(int position)类型和getViewTypeCount()类型总数,如图:
.
但是前几天在做listview展示多个类型的时候,出现了一个错误IndexOutOfBoundsException
找了好久就是不知道怎么回事,经过一天的艰难探索,终于找到了突破点。查看源码发现类型的position必须从0开始,如图
我的需求是reply == null加载一个布局,reply != null加载另一个布局,本以为getItemViewType(position);中的position可以随便写一个整数,结果导致了这个错误。
发现错误就要解决错误,只需要把getItemViewType(position)中的position修改为从0开始。即int posi = 0;这个错误完美解决。。
问题二:
但是接着运行程序之后又报了类型转化错误java.lang.ClassCastException: com.xingtong.qiaoyuer.adapter.v_1_1.SalonTalkAdapter$ViewHolder2 cannot be cast to com.xingtong.qiaoyuer.adapter.v_1_1.SalonTalkAdapter$ViewHolder1
大概意思就是ViewHolder2不能转化为ViewHolder1,原因就是数据源开始只有type==0类型的数据,所以这时候convertView已经被实例化了,convertView已经不为null了,但是我在listview上拉加载更多数据的时候,又会加载出第二个Type的即 type==1的数据源,此时再次执行到convertView的时候发现,convertView已经不为null了,就会直接从getTag()=ViewHolder2中取出ViewHolder2中的控件值,其实理论上应该走的是TYpe
==1,ConvertView==null 那么从新实例化ConvertView ,然后convertView.setTag(ViewHolder1);理想状态下应该是发现Type==1时,发现type==1的converView没有实例化,则先实例化,发现type
==0的convertView没有实例化,则先实例化。怎样才能做到一个type类型对应一个convertView呢?就是要在数据源的时候设置上Type的类型。如图2
(要是服务器返回的数据源带有类型就好了,就不用自己把list中的每一个对象都拿出来加上type然后再放进去了)。
其实在适配器Adapter执行的过程中先执行的getItemViewType(int position)方法和getViewTypeCount()类型总数方法,然后才走的getView()方法,所以形成了数据源的type一一对应的关系后,当它拿到一个bean对象的数据后发现Type和上一个bean对象的数据不一致,它就会重新初始化ConvertView,从新setTag(ViewHolder)。以此类推以后再遇到有相同类型的就直接拿以前的ViewHolder,如果没有就从新再次初始化ConvertView。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories