解决ListView中滑动复用时控件的混乱问题
来源:互联网 发布:三天学会mysql 编辑:程序博客网 时间:2024/04/27 23:42
这个问题恐怕很多人在刚开始使用ListView时都接触到过,就是比如listview的item中有一个Button或一个CheckBox,你明明点击按键改变了他的背景图片或者问题,又或者勾选了CheckBox,但是你一滑动,发现下面你没操作的item也跟着改变了,然后你再滑动回去,结果原来item上面的操作又变没了。这就是listview中item复用时所产生的问题,下面这种图就是例子。
上图就是例子,下滑时,下面明明没有勾选的CheckBox也被勾选上了。当然 这里只是两个例子,群里的小伙伴问过几次,有的item点击字体变色,滑动时没了之类的,这些都同属于一个原理。那么该如何解决这个问题呢?
先分析下这个问题出现的原因:
listview作为一个能加载理论上无限数据的控件,他本是是不存在储存那么多item的空间的,他其实实现了一个复用的机制。先看下面这张图,图是百度的,我自己花了一份 ,太难看了,意思是一样的。
上图中一个listview有7个item,但是当他上滑是,item1渐渐消失,item8出来,其实这时候产生的item8出现的的部分就是item1消失的部分,这就是listview的复用,在这种机制下,其实这个listview总共就是对着7个item的操作,却完成了对N多数据的加载。但是这种方法就出现了上述的问题,他会时控件的事件错乱,比如item1中有一个checkbox勾选了,上拉后,item8复后,连勾选这个图像一起复用了,所以导致了listview不断滑动过程中,checkbox的勾选情况不断变化的情况。那么这种情况如何解决呢?
看下面代码:
public class TestAdapter extends BaseAdapter{ private List<String> list; private Context context; ViewHolder holder = null; public static HashMap<Integer,Boolean> isCheck; public static HashMap<Integer,Boolean> isSelect; public TestAdapter(List<String> list, Context context) { this.list = list; this.context = context; isCheck = new HashMap<Integer,Boolean>(); isSelect = new HashMap<Integer,Boolean>(); initData(); } private void initData() { for(int i = 0;i< list.size();i++){ isCheck.put(i,false); setIsCheck(isCheck); isSelect.put(i,false); } } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { if(convertView == null){ holder = new ViewHolder(); convertView = LayoutInflater.from(context).inflate(R.layout.item,parent,false); holder.button = (Button) convertView.findViewById(R.id.button); holder.checkBox = (CheckBox) convertView.findViewById(R.id.check_box); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } holder.checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(getIsCheck().get(position)){ isCheck.put(position, false); setIsCheck(isCheck); }else{ isCheck.put(position, true); setIsCheck(isCheck); } } }); holder.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isSelect.get(position)) { holder.button.setText("按下去"); isSelect.put(position, false); notifyDataSetChanged(); } else { holder.button.setText("弹出来"); isSelect.put(position, true); notifyDataSetChanged(); } } }); if(isSelect.get(position)) { holder.button.setText("按下去"); }else{ holder.button.setText("弹出来"); } if(getIsCheck().get(position)){ holder.checkBox.setChecked(true); }else{ holder.checkBox.setChecked(false); } return convertView; } class ViewHolder{ Button button; CheckBox checkBox; } public static HashMap<Integer,Boolean> getIsCheck(){ return TestAdapter.isCheck; } public static void setIsCheck(HashMap<Integer,Boolean> isCheck){ TestAdapter.isCheck = isCheck; }}
在这里,我举了两个例子,一个是checkbox,一个是button,当然解决办法也是一样的,这是为了说明其实解决错乱的方法原理是一样的,不管是我写的这俩个,还是item字体颜色的变化之类的。
代码中,我用了HashMap来保存两个数据,第一个就是item的position值,这个值表示的是item真正在listview的序号而不是页面上这个item所在的序号。第二个则是这个position的事件情况,我这里用false表示未勾选,true表示勾选。
第一步:先将listview中所有的checkbox的勾选情况设为false,然后存入HashMap中,然后这段代码
holder.checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(getIsCheck().get(position)){ isCheck.put(position, false); setIsCheck(isCheck); }else{ isCheck.put(position, true); setIsCheck(isCheck); } } });
当你点击时,改变勾选情况,并将改变的情况在HashMap中更新,这里我写了这两个可供外部调用的方法
public static HashMap<Integer,Boolean> getIsCheck(){ return TestAdapter.isCheck; } public static void setIsCheck(HashMap<Integer,Boolean> isCheck){ TestAdapter.isCheck = isCheck; }
是为外部不如需要全选或不全选时所使用的,你不用也行,那就像我button的那样写。在HashMap存入数据后,在最后一段
if(getIsCheck().get(position)){ holder.checkBox.setChecked(true); }else{ holder.checkBox.setChecked(false); }
中设置checkbox的勾选情况,这样事件就是根据HashMap中存入的数据来判断,而不是复用时的直接使用了,最后附一张完成图。
- 解决ListView中滑动复用时控件的混乱问题
- 关于ListView滑动混乱问题
- 在ListView控件中添加head视图为ViewPager时遇到的问题是滑动出现混乱。
- 解决React Native中ListView控件在ios上不能滑动的问题
- ListView中View的显示混乱问题
- Android中ListView滑动时数据混乱
- 解决!Gallery中嵌套ListView,Gallery不能滑动的问题
- 解决ListView在ScrollView中滑动冲突的问题
- Android ScrollView中嵌套ListView,滑动冲突问题的解决
- Android ScrollView中嵌套ListView,滑动冲突问题的解决
- ListView+CheckBox解决复选框混乱的问题
- 解决ListView内置选择框复用混乱的问题
- 解决 ScrollView和ListView连用时的滑动冲突和显示不正常
- listview 滑动混乱
- Android完美解决ListView复用导致的Checkbox状态混乱问题
- android中关于listView复用时出现错乱问题
- 解决listView和ViewPager的滑动问题
- ListView中item progressbar显示混乱的问题
- hive使用rank实现topN的查询
- iOS navigation UIBarButtonItem 风格
- Uboot 2014.07 makefile分析
- 学习日记--PopupWindow简单功能实现
- zzulioj 1831: 周末出游 (vector&&dfs)
- 解决ListView中滑动复用时控件的混乱问题
- CommonTableCollectView:图片懒加载,不使用的image大量释放
- 92,内存管理(四)
- 【负载均衡】四层和七层负载均衡的区别
- 如何写出高性能SQL语句
- Eclipse在Debug时不在指定位置暂停
- js 分页
- 友盟的常见使用----三方登陆、分享和“埋点”(友盟统计)
- Flume架构与源码分析-核心组件分析-2