最近项目中,使用了SimpleAdapter给ListView绑定数据。遇到了一个非常奇怪的问题,调试了好久,终于找到问题了,不敢独享...
以下代码中的数据是构造的,但是原理一样。
以下构造了20组数据,用来传给SimpleAdapter:
-
List<Map<String, Object>> items = new ArrayList<Map<String, Object>>();
-
for (int i = 1; i <= 10; i++) {
-
Map<String, Object> itemMap= new HashMap<String, Object>();
-
itemMap.put("name", i);
-
itemMap.put("isdefined", 0);
-
items.add(itemMap);
-
}
-
for (int i = 11; i <= 20; i++) {
-
Map<String, Object> itemMap= new HashMap<String, Object>();
-
itemMap.put("name", 1);
-
itemMap.put("isdefined", "");
-
items.add(itemMap);
-
}
以下为SimpleAdapter的实现:
-
public SimpleAdapter setAdapter(final Activity myActivity,List<Map<String, Object>> items){
-
String[] nameArray={"isdefined", "name"};
-
int[] ids={R.id.my_list_item_isdefined, R.id.my_list_item_name};
-
SimpleAdapter adapter = new SimpleAdapter(myActivity,(List<? extends Map<String, ?>>) items,
-
R.layout.my_list_item, nameArray,ids);
-
adapter.setViewBinder(new ViewBinder() {
-
private String isdefined;
-
public boolean setViewValue(View view, final Object data, String textRepresentation) {
-
if(view.getId() == R.id.my_list_item_isdefined){
-
isdefined=textRepresentation;
-
return true;
-
} else if(view.getId() == R.id.my_list_item_name){
-
if(isdefined!= null && isdefined.equals("1")){
-
view.setVisibility(View.VISIBLE); //此控件默认不显示,只有isdefined=1才显示
-
view.setOnClickListener(new OnClickListener(){
-
-
@Override
-
public void onClick(View arg0) {
-
// TODO Auto-generated method stub
-
Log.v(TAG, "name- " + textRepresentation);
-
}
-
});
-
} else {
-
view.setVisibility(View.GONE); //最初的实现没有此处代码
-
}
-
return true; //返回true是必须的,你懂得
-
}
-
return false;
-
}
-
});
-
return adapter;
-
}
需求:
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) |