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 ...
随机推荐
- C#中的枚举类型
浅谈C#中的枚举 转自http://www.cnblogs.com/liyingyi/archive/2005/12/28/306772.aspx 枚举类型是一种的值类型,它用于声明一组命名的常 ...
- [转]spring mvc注解方式实现向导式跳转页面
由于项目需要用到向导式的跳转页面效果,本项目又是用spring mvc实现的,刚开始想到用spring 的webflow,不过webflow太过笨重,对于我们不是很复杂的跳转来说好像有种“杀鸡焉用牛刀 ...
- log4j日志输出配置
# Configure logging for testing: optionally with log filelog4j.rootLogger=WARN, stdoutlog4j.rootLogg ...
- OC弱语法
OC是在运行过程中才会检测对象有没有实现相应的方法,所有编译过程只给出警告:可能找不到对应方法: 如果程序在运行过程中出错,就会出现程序闪退: 类方法:类可以直接调用的方法,相当于java中的 ...
- 不要伤害指针(5)--void和void指针详解
原文转载地址:http://blog.csdn.net/sunchaoenter/article/details/6587426 增加自己的想法,作为笔记. 1.概述 许多初学者对C/C++语言中的v ...
- 图解MYSQL JOIN ON,SQL JOIN 详解,数据库sql join语句
对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codin ...
- linux 下eclipse配置apache服务器,选中server时server name为灰色状态
后来发现,没有创建
- php配置redis支持
在php.ini里面添加下面两行,注意这两行的顺序一定不要颠倒(扩展库下载网址https://github.com/phpredis/phpredis/downloads),同时注意这2个文件的版本一 ...
- [LeetCode]题解(python):155-Min Stack
题目来源: https://leetcode.com/problems/min-stack/ 题意分析: 实现一个小的栈,包括初始化,push,pop,top,和getMin. 题目思路: 私用是用两 ...
- 12.java.lang.NoSuchMethodException
java.lang.NoSuchMethodException 方法不存在异常 当程序试图通过反射来创建对象,访问(修改或读取)某个方法,但是该方法不存在就会引发异常