使自定义ListView中的复选框正常工作

时间:2011-09-04 15:03:30

标签: android listview checkbox adapter

我所拥有的是我的listview的自定义行布局:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<CheckBox
android:id="@+id/chkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

我在活动中使用此布局作为我的适配器:

adapter = new AdapterCustomBoxes(context, R.layout.custom_check_row, (ArrayList<Map<String, String>>) list_values);
list.setAdapter(adapter);    
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

这是一个适配器,这是我的适配器的getView方法:

public class AdapterCustomBoxes extends ArrayAdapter<Map<String, String>> {

private List<Map<String, String>> list;
private List<Map<String, String>> orig_list;

private Context upper_context;
private View view;

public AdapterCustomBoxes(Context context, int textViewResourceId, ArrayList<Map<String, String>> items) {
    super(context, textViewResourceId, items);

    this.list = items;
    this.orig_list = items;
    this.upper_context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

view = convertView;

if (view == null) {
    LayoutInflater vi = (LayoutInflater)upper_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = vi.inflate(R.layout.custom_check_row, null);
}

Map<String, String> selectedgroup = new HashMap<String, String>();
selectedgroup = (Map<String, String>) list.get(position);
String itemtext = (String) selectedgroup.get("item_text");

TextView row_text = (TextView) view.findViewById(R.id.text);

row_text.setText(itemtext);

return view;
}
}

现在到了我感到困惑的地步。当我选中其中一个复选框时,单击的复选框将被选中。但是没有任何逻辑,其他行的复选框也会被检查。如果我然后滚动列表,每个框的检查状态可能会从我遇到这一行到下一次更改。

那么这里有什么问题?

我已经尝试向适配器中的视图添加onclicklistener,然后在触发此侦听器时将显式复选框设置为cheched / unchecked,但这也无法正常工作,我点击了一个框并且另一个人接受了检查。

所以我想这是回收视图的问题?我是否必须单独存储已检查的状态,并且每次在getView方法中恢复它都可以解决这个问题吗?或者有更简单的方法吗?请帮忙;)

那么有人可以给我一个暗示吗?太多了!

---编辑---

所以我现在试图保存复选框的状态是创建一个地图:

private Map<View, Boolean> itm = new HashMap<View, Boolean>();

并在getView方法中单击框时保存状态:

CheckBox chkbox = (CheckBox) view.findViewById(R.id.chkbox);

    chkbox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener(){
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            itm.put(buttonView, isChecked);
        }               
    });

    if(itm.containsKey(chkbox)){
        iteminfo_row_chkbox.setChecked( itm.get(chkbox) );
    }else{
        iteminfo_row_chkbox.setChecked(false);
    }

对不起,如果这是完全错误的方法,但不应该这样做吗?结果与整个列表和检查状态不正确的结果相同,我做错了什么?

2 个答案:

答案 0 :(得分:0)

一些偏离主题的评论:

首先你不需要这个:

Map<String, String> selectedgroup = new HashMap<String, String>();

你可以这样做:

Map<String, String> selectedgroup = (Map<String, String>) list.get(position);

另外,您确定需要TextView吗?该复选框也可以保存文本。

关于您的问题,如何保存选中的复选框?您应该在返回视图时设置复选框,特别是在重复使用视图时。

- 编辑 -

为什么不创建这样的私有类?

private class ListItem{
    String text;
    boolean value;
}

然后您可以只使用List<Map<String,String>>代替List<ListItem>

关于onCheckedChangeListener,您可以使用复选框中的文本迭代列表以找到正确的位置,然后更改值。如果文字不是唯一的, 而不是使用onCheckedChangeListener,您可以在ListView上使用OnItemClickListener来保存点击的位置。

答案 1 :(得分:0)

好吧我想我得到了它,我使用了选定组映射中的静态id值作为itm映射中的键来查找复选框的选中/未选中状态。使用视图是错误的方法,因为它们不能用作密钥。