android listview 重用view导致的选择混乱问题
20150526
listview是常用的控件,经常用自定义的adapter,为了提高显示效率,常利用view的重用方式防止重绘,但因为重用利用的是旧的view,常导致显示的数据会由于position的位置出现错乱。在一个app项目中我遇到过多次这个问题,包括带Button的都能很好的解决,但今天遇到listview中的item有togglelbutton的情况,绑定的监听器是togglebutton的CompoundButton.OnCheckedChangeListener(),竟然出现了问题,一直没有解决,最后将item的监听换成了View.OnClickListener()才解决问题。
一般,为了防止数据混乱,会在convertview判断null的if-else之后再获取list里的显示数据。getview的例子如下:
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
final ViewHolder holder;
// 优化listview --去掉重用,防止togglebutton的点击位置记录出错
if(convertView == null)
{
// 使用自定义的布局
holder = new ViewHolder();
convertView = mInflater
.inflate(R.layout.list_invite_party_member, null);
// 初始化布局中的元素
holder.ivAvatar = (ImageView) convertView.findViewById(R.id.iv_avater);
holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
holder.tvTag = (TextView) convertView.findViewById(R.id.tv_tag);
holder.btnSelect = (ToggleButton) convertView
.findViewById(R.id.btn_select);
holder.linearLayout = (LinearLayout) convertView
.findViewById(R.id.rl_friend_item);
convertView.setTag(holder);
} else
{
holder = (ViewHolder)convertView.getTag();
} // 绑定数据
final int index = position;
UserBean bean = listFriend.get(index);
// 设置头像
if (!TextUtils.isEmpty(bean.getUserAvatar()))
{
String avatarUrl = Constant.URL_USER_AVATER + bean.getUserAvatar();
// 初始化异步加载头像对象
finalBitmap = FinalBitmap.create(context);
finalBitmap.configLoadingImage(R.drawable.user_head_02);
finalBitmap.display(holder.ivAvatar, avatarUrl);
} else
{
holder.ivAvatar.setImageResource(R.drawable.user_head_02);
} if (!TextUtils.isEmpty(bean.getUserNickname()))
{
holder.tvName.setText(bean.getUserNickname());
} else
{
holder.tvName.setText(bean.getUserPhone());
}
if (!TextUtils.isEmpty(CommonUtils.getUserTags(bean)))
{
holder.tvTag.setText(CommonUtils.getUserTags(bean));
holder.tvTag.setVisibility(View.VISIBLE);
} else
{
holder.tvTag.setVisibility(View.GONE);
}
if (TextUtils.equals(bean.getReserved01(), "1"))
{
// 已添加的场合显示为 删除
holder.btnSelect.setChecked(true);
} else
{
holder.btnSelect.setChecked(false);
}
holder.btnSelect.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
ToggleButton view = (ToggleButton)v;
//boolean isCheckedOld = view.getText().toString().equals("添加")?true:false;
// 获取最新的点击后check状态
boolean isChecked = view.isChecked();
if (isChecked)
{
// 添加了该人,button显示删除
view.setChecked(true);
listFriend.get(index).setReserved01("1"); } else
{
// 原来是被选中的,点击后该人被删除
// 删除了该人,button显示添加
view.setChecked(false);
listFriend.get(index).setReserved01("0");
}
}
});
/* holder.btnSelect
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{ @Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked)
{ LogUtil.d("isChecked= " + isChecked );
LogUtil.d("index= " + index );
// TODO Auto-generated method stub
if (isChecked)
{
// 添加了该人,button显示删除
listFriend.get(index).setReserved01("1");
} else
{
// 删除了该人,button显示添加
listFriend.get(index).setReserved01("0");
}
}
});*/
return convertView;
} /**
* 布局中的元素
*/
class ViewHolder
{
ImageView ivAvatar;
TextView tvName;
TextView tvTag;
ToggleButton btnSelect;
LinearLayout linearLayout;
}
并且用final的index记住了数据的位置,在下面button监听的动作中就可以获得正确的数据了。
但是试验发现(注释掉的部分)利用此方法还是不可以,可能是CompoundButton.OnCheckedChangeListener()的问题吧。利用此监听器监听button的动作改变list相应数据会导致位置混乱。只好借用View.OnClickListener()来控制togglebutton的显示了。倒也不算麻烦,本来togglebutton就一般是这两种控制方式。还有要注意的是只要点击的togglebutton,它的check状态就会变,在View.OnClickListener()中也是一样。
mark一下,所以利用adapter记住btn的状态这件事还是很简单的,就是没有理解到CompoundButton的机制而导致的失败,还好有View.OnClickListener()成功的先例,要不然每个view都绘制list数据很多的话也太不现实了。还有一个checkbox的item没有尝试,不行的话还是要用button或View.OnClickListener()来替代了。
android listview 重用view导致的选择混乱问题的更多相关文章
- Android ListView 中加入CheckBox/RadioButton 选择状态保持、全选、反选实现
最近在一个项目中,需要在ListView的item中加入CheckBox,但是遇到的一个问题是上下滑动的时候如果有选择了的CheckBox,就会出现选择项错误的问题,下面将个人的解决方法总结如下;先说 ...
- Android ListView 显示多种数据类型
ListView往往可能会有不同的数据类型,单类型的数据可能运用会比较少些,这也是最近项目中的一个需求{在发送消息的时候,需要选择联系人,而联系人列表由英文字母索引+联系人组成},上一篇文章只是一个基 ...
- Android ListView批量选择(全选、反选、全不选)
APP的开发中,会常遇到这样的需求:批量取消(删除)List中的数据.这就要求ListVIew支持批量选择.全选.单选等等功能,做一个比较强大的ListView批量选择功能是很有必要的,那如何做呢? ...
- android 修改listview item view 的方法(转)
android 修改listview item view 的方法 具体的解答办法很简单: 代码如下 : 1.获取需要更新的view int visiblePosition = mListView. ...
- Android精通:View与ViewGroup,LinearLayout线性布局,RelativeLayout相对布局,ListView列表组件
UI的描述 对于Android应用程序中,所有用户界面元素都是由View和ViewGroup对象构建的.View是绘制在屏幕上能与用户进行交互的一个对象.而对于ViewGroup来说,则是一个用于存放 ...
- Android ListView getView()方法重复调用导致position错位
问题现状:Android ListView getView()方法重复调用导致position错位 解决办法:把ListView布局文件的layout_height属性改为fill_parent或者m ...
- 【Android UI】Android开发之View的几种布局方式及实践
引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...
- 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...
- Android listview与adapter用法
listview与adapter用法 博客分类: android 一个ListView通常有两个职责. (1)将数据填充到布局. (2)处理用户的选择点击等操作. 第一点很好理解,ListView ...
随机推荐
- Codeforces 325E
Codeforces 325E 原题 题目描述:给出\(n\)个点, 编号为\(0 \text ~ n-1\),每个点连出两条边分别为\(2i\)和\(2i+1\)(\(mod n\)),现从\(0\ ...
- Xshell中文乱码
终端”编码设置,默认是 默认语言,选择UTF8设置即可
- WMware VMX格式转换成OVF
1.关于VMX格式 vmx文件是vmware虚拟机系统的配置文件,注意:刚刚安装好VMware Workstation以后是找不到这个文件的,当你在VMware Workstation中建立了一个虚拟 ...
- Android的logcat命令详解
前言 欢迎大家我分享和推荐好用的代码段~~ 声明 欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net ...
- git 删除远程主分支及其它操作
1. 删除远程分支 如果不再需要某个远程分支了,比如搞定了某个特性并把它合并进了远程的 master 分支(或任何其他存放稳定代码的地方),可以用这个非常无厘头的语法来删除它:git push [远程 ...
- Javascript 常用
第一步,实现百度输入法的页面布局 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- 红豆带你从零学C#系列—Visual Studio工具介绍、下载和安装
一.Visual Studio的下载 Visual Studio(简称VS)是微软的一套完整的开发工具集,集成了能够开发并运行如C#.C++.VB.F#等程序的开发环境,目前最新的版本是Visual ...
- 如何在Eclipse中开发并调试自己的插件(或者说如何将自己的代码插件化)
Setting up Eclipse to create and debug plugins for ImageJ 最近在做一个关于卫星遥感全链路仿真的项目,由于项目是基于ImageJ开发,而Imag ...
- error C4996 The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
error C4996: 'strupr': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ co ...
- 浅谈C中的指针和数组(一)
本文转载地址:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242138.html 在原文的基础上加入自己的想法作为修改. 指针是C/C ...