Chinaunix首页 | 论坛 | 博客
  • 博客访问: 465054
  • 博文数量: 145
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1060
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-22 11:52
个人简介

专注计算机技术: Linux Android 云计算 虚拟化 网络

文章分类

全部博文(145)

文章存档

2016年(3)

2015年(21)

2014年(75)

2013年(46)

我的朋友

分类: Android平台

2014-01-29 02:00:19

最近项目中,使用了SimpleAdapter给ListView绑定数据。遇到了一个非常奇怪的问题,调试了好久,终于找到问题了,不敢独享...

以下代码中的数据是构造的,但是原理一样。

以下构造了20组数据,用来传给SimpleAdapter:

点击(此处)折叠或打开

  1. List<Map<String, Object>> items = new ArrayList<Map<String, Object>>();
  2. for (int i = 1; i <= 10; i++) {
  3. Map<String, Object> itemMap= new HashMap<String, Object>();
  4. itemMap.put("name", i);
  5. itemMap.put("isdefined", 0);
  6. items.add(itemMap);
  7. }
  8. for (int i = 11; i <= 20; i++) {
  9. Map<String, Object> itemMap= new HashMap<String, Object>();
  10. itemMap.put("name", 1);
  11. itemMap.put("isdefined", "");
  12. items.add(itemMap);
  13. }
以下为SimpleAdapter的实现:

点击(此处)折叠或打开

  1. public SimpleAdapter setAdapter(final Activity myActivity,List<Map<String, Object>> items){
  2.         String[] nameArray={"isdefined", "name"};
  3.         int[] ids={R.id.my_list_item_isdefined, R.id.my_list_item_name}; 
  4.          SimpleAdapter adapter = new SimpleAdapter(myActivity,(List<? extends Map<String, ?>>) items,
  5.                                                      R.layout.my_list_item, nameArray,ids);
  6.      adapter.setViewBinder(new ViewBinder() {
  7.           private String isdefined;
  8.           public boolean setViewValue(View view, final Object data, String textRepresentation) {
  9.           if(view.getId() == R.id.my_list_item_isdefined){                     
  10.                isdefined=textRepresentation;
  11.                return true;
  12.           } else if(view.getId() == R.id.my_list_item_name){
  13.                if(isdefined!= null && isdefined.equals("1")){
  14.                    view.setVisibility(View.VISIBLE); //此控件默认不显示,只有isdefined=1才显示
  15.                     view.setOnClickListener(new OnClickListener(){
  16.                       
  17.                             @Override
  18.                             public void onClick(View arg0) {
  19.                                 // TODO Auto-generated method stub
  20.                                 Log.v(TAG, "name- " + textRepresentation);
  21.                             }                            
  22.                    });
  23.                } else {
  24.                    view.setVisibility(View.GONE); //最初的实现没有此处代码
  25.                 }
  26.                return true; //返回true是必须的,你懂得
  27.           }
  28.      return false;
  29.      }
  30.      });
  31.      return adapter;
  32.     }
需求:
1. 只有isdefined值为1时,R.id.my_list_item_name才显示,否则不显示(默认是不显示的)

问题描述:
1. 第一次加载1-10项数据时,因为isdefined为0,都不显示,表现正常。
2. 第一次加载11-20项,因为isdefined为1,都显示,也正常。
3. 由于项目已经超过了一屏,当往上滑动屏幕重新倒序显示10至1项时,发现R.id.my_list_item_name竟然显示出来了,真是非常奇怪。
 isdefined值确实为0啊, view.setVisibility(View.VISIBLE)没有执行,怎么还显示呢? 

4. 想来想去,想不出问题所在。于是,手工试验,将view.setVisibility(View.GONE)显式的调用了,结果一切正常。

思考:
当SimpleAdapter因为显示需要重新构造ListItem项时,如果setViewValue值返回false,就不可控了,由系统自己决定。但是由于该处应用的特殊性,如果由系统自己决定,会将传入的值显示到该控件中,这并不是我想要的结果,此处只是想借该控件把这个值与其关联。
由于setViewValue对于该控件一直是返回true,当不满足isdefined=1的条件时,造成了系统不管,setViewValue又管的出人意料的情况。情形应该是这样的,setViewValue取到了上一次需要构造listview item的相同ID的控件的处理方式。根据运行情况,可以验证了此猜想,并且取的值是放在栈
。 描述了大概原理,如有问题,请指出,谢谢!

结论:
对于SimpleAdapter中的数据,有特殊要求的,一定要显式指定,否则,会出现意想不到的结果。
阅读(1811) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~