Tab Layout中自定义ListView项乱序问题求助
问题原因分析
兄弟,你的Tab里ListView项乱序、跨页面串数据的问题,根源出在错误实现了ListView适配器的视图类型方法,再加上getView没有正确复用视图导致的:
- 错误重写
getItemViewType和getViewTypeCount:这两个方法是用来处理列表中不同布局样式的item的(比如有的item是纯文字,有的是图文混合),但你的所有item都用同一个R.layout.itemview布局,完全不需要自定义这两个方法。你现在把每个position都当成独立的视图类型,还把视图类型数量设为列表长度,这会让ListView彻底放弃视图复用机制——它会认为每个item都是独一无二的,每次滚动都创建新View,不仅性能拉胯,还会和ViewPager的页面复用逻辑冲突,导致不同Tab的列表数据串在一起。 getView没有复用convertView和ViewHolder:你每次调用getView都直接inflate新布局,还每次都new一个Holder,没有利用convertView的复用机制,也没有用setTag/getTag缓存ViewHolder,这会让滚动时视图和数据的绑定彻底混乱。
修复方案
直接按下面的步骤修改你的适配器:
1. 删除错误的视图类型方法
把这两个完全没必要的方法删掉:
public int getViewTypeCount() { if(title.size()==0){ return 1; } return title.size(); } @Override public int getItemViewType(int position) { return position; }
2. 修复getView方法,实现视图复用
修改getView方法,正确复用convertView和ViewHolder:
@Override public View getView(int i, View view, ViewGroup viewGroup) { Holder holder; // 检查convertView是否为空,为空才创建新视图 if (view == null) { holder = new Holder(); view = inflater.inflate(R.layout.itemview, viewGroup, false); holder.tvtitle = view.findViewById(R.id.title); holder.ivimage = view.findViewById(R.id.image); holder.tvprice = view.findViewById(R.id.price); holder.tvdesc = view.findViewById(R.id.description); // 把Holder缓存到View的Tag里 view.setTag(holder); } else { // 直接从Tag里取出缓存的Holder holder = (Holder) view.getTag(); } // 绑定数据 holder.tvtitle.setText(title.get(i)); holder.ivimage.setImageResource(image.get(i)); holder.tvprice.setText(price.get(i)); holder.tvdesc.setText(desc.get(i)); return view; }
额外优化建议
- 建议把你的数据封装成一个单独的Model类,比如
Product,把image、title、price、desc都放在这个类里,然后用ArrayList<Product>来存储数据,这样比维护四个独立的ArrayList更清晰,也不容易出错。 - 如果你的Tab是用ViewPager实现的,确保每个Tab对应的Fragment(或页面)都持有独立的适配器和数据集合,不要多个Tab共用同一个适配器实例。
这样修改后,ListView的视图复用机制就能正常工作,Tab之间的列表数据也不会再串位了。
内容的提问来源于stack exchange,提问作者Himanshu Gautam
相关产品推荐
相关产品推荐

