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导致的选择混乱问题的更多相关文章

  1. Android ListView 中加入CheckBox/RadioButton 选择状态保持、全选、反选实现

    最近在一个项目中,需要在ListView的item中加入CheckBox,但是遇到的一个问题是上下滑动的时候如果有选择了的CheckBox,就会出现选择项错误的问题,下面将个人的解决方法总结如下;先说 ...

  2. Android ListView 显示多种数据类型

    ListView往往可能会有不同的数据类型,单类型的数据可能运用会比较少些,这也是最近项目中的一个需求{在发送消息的时候,需要选择联系人,而联系人列表由英文字母索引+联系人组成},上一篇文章只是一个基 ...

  3. Android ListView批量选择(全选、反选、全不选)

    APP的开发中,会常遇到这样的需求:批量取消(删除)List中的数据.这就要求ListVIew支持批量选择.全选.单选等等功能,做一个比较强大的ListView批量选择功能是很有必要的,那如何做呢? ...

  4. android 修改listview item view 的方法(转)

    android 修改listview item view 的方法   具体的解答办法很简单: 代码如下 : 1.获取需要更新的view int visiblePosition = mListView. ...

  5. Android精通:View与ViewGroup,LinearLayout线性布局,RelativeLayout相对布局,ListView列表组件

    UI的描述 对于Android应用程序中,所有用户界面元素都是由View和ViewGroup对象构建的.View是绘制在屏幕上能与用户进行交互的一个对象.而对于ViewGroup来说,则是一个用于存放 ...

  6. Android ListView getView()方法重复调用导致position错位

    问题现状:Android ListView getView()方法重复调用导致position错位 解决办法:把ListView布局文件的layout_height属性改为fill_parent或者m ...

  7. 【Android UI】Android开发之View的几种布局方式及实践

    引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...

  8. 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...

  9. Android listview与adapter用法

    listview与adapter用法 博客分类: android   一个ListView通常有两个职责. (1)将数据填充到布局. (2)处理用户的选择点击等操作. 第一点很好理解,ListView ...

随机推荐

  1. 在CGridView调用CJuiDialog的弹出层

    <?php $this->widget('zii.widgets.grid.CGridView', array(    'id'=>'user-grid',    'dataProv ...

  2. 正式生产环境下hadoop集群的DNS+NFS+ssh免password登陆配置

    博客地址:http://www.loveweir.com/ 环境虚拟机centos6.5 主机名h1  IP 192.168.137.11  作为DNS FNS的server 主机名h2  IP 19 ...

  3. oj 小黑华丽的逆袭机会

    Problem H: 小黑华丽的逆袭机会 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 79  Solved: 7 [Submit][Status][ ...

  4. django中怎样生成非HTML格式的内容。

    某些时候可能有这种需求.在网页中点击一个链接或者一个button希望返回一张图片.一个pdf文档.一个csv文档等而非HTML. 在diango中非常easy做到这些.django中的view用来接收 ...

  5. 《think in python》学习-1

    高能提示:本文大量编程术语与释义,一些释义如有偏差恕不讨论. 纠结学Python 很久了,一年的纠结过程中慢慢的积累了一点对python的认知,但实际语法都未曾接触过,研究backbone的一个例子的 ...

  6. Power Designer Repository 使用指南(一)

    最近wait4friend在进行建模的时候,总是被问如果在Power Designer里面进行版本的控制.原始的方法是对PDM文件进行SVN管理,不过这个方法比较土,并且不方便版本直接图形的比较.其实 ...

  7. iOS的Ping++支付接入步骤(详细)

    Ping++ SDK 代码下载地址: https://github.com/CoderLeezhen/PingppDemo 参考链接: https://www.pingxx.com/guidance/ ...

  8. Javaweb整合mongo和kettle6.0的环境配置

    为了编译能通过,maven需要加入仓库地址以及一些必须要的包的依赖情况: pentaho中央仓库: 在properties里面配置版本号: <kettle.version>6.0.0.0- ...

  9. poj1323--贪心算法

    题意:一群人打牌包括你,每人出一张牌,谁最大,谁就算赢一局,问你最少能赢几局? 给出人数N,每人的牌数M,及你的牌. 分析:1.这题需比较大小,就像我们打牌时要将牌排序以便出牌,显然要先将手上的牌进行 ...

  10. 利用汇编查看C++函数调用

    这篇文章的内容是一个老生常谈的问题----> 函数是如何被调用的. 本文用汇编代码研究函数调用的过程,参数调用的方式,函数值的返回. 1. 函数是如何实现调用的 函数的调用是用call 和 re ...