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. jquery Ztree v3.5 实例2 自定义显示在节点前的图片

    显示效果如下: 代码如下: <html> <head><title></title></head> <script type=&quo ...

  2. 【数据库】SQL优化方法汇总

    最近在研究SQL语句的优化问题. 下面是从网上搜集的,有的地方有点老了,可是还是有很多可以借鉴的地方的. 如何加快查询速度? 1.升级硬件. 2.根据查询条件,建立索引,优化索引.优化访问方式,限制结 ...

  3. 《Oracle Applications DBA 基础》- 9 - Concurrent Processing[Z]

    <Oracle Applications DBA 基础>- 9 - Concurrent Processing================================== 参考资料 ...

  4. eclipse中输入的中文为繁体的问题

    今天在eclipse中编写注释的时候发现,输入的中文都为繁体,且只在eclipse编辑器中为繁体,切换到网页中则为正常. 最后发现,竟然是输入法的shift+ctrl+F快捷键和eclipse的冲突. ...

  5. struts2中使用json插件实现ajax交互

    json插件可以简单的实现ajax交互,避免了使用struts2-dojo-plugin.jar包时带来的struts2.x版本冲突问题.并且减少了使用ajax标签时需要的繁琐的配置包括web.xml ...

  6. hadoop笔记之MapReduce原理

    MapReduce原理 MapReduce原理 简单来说就是,一个大任务分成多个小的子任务(map),并行执行后,合并结果(reduce). 例子: 100GB的网站访问日志文件,找出访问次数最多的I ...

  7. Facebook 调试工具Stetho配置入门

    I decided to spend a few hours on Stetho.Stetho is a sophisticated debug bridge for Android applicat ...

  8. nodejs 下载网页及相关资源文件

    功能其实很见简单,通过 phantomjs.exe 采集 url 加载的资源,通过子进程的方式,启动nodejs 加载所有的资源,对于css的资源,匹配css内容,下载里面的url资源 当然功能还是很 ...

  9. 解析:用 CSS3 和 JavaScript 制作径向动画菜单

    原作者的解析(英文):http://creative-punch.net/2014/02/making-animated-radial-menu-css3-javascript/ 原作者的解析(译文) ...

  10. byte与sbyte的转换

    C#实现byte与sbyte的转换 byte[] mByte; sbyte[] mSByte = new sbyte[mByte.Length]; ; i < mByte.Length; i++ ...