Getting Checkboxes in a custom ListView to work properly
what i do have is a custom row layout for my 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>
I am using this layout for my adapter in the activity:
adapter = new AdapterCustomBoxes(context, R.layout.custom_check_row, (ArrayList<Map<String, String>>) list_values);
list.setAdapter(adapter);
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
And an adapter for that, here is the getView method of my adapter:
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, V开发者_Python百科iewGroup 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;
}
}
And now here comes the point where i get confused. When i check one of those checkboxes the clicked one gets checked. But without any logic somes of the other line's checkboxes also get checked. And if i then scroll the list the checked status of each box may change from one time i come across this line to the next time.
So what is the problem here?
I already tried to do add an onclicklistener to the view in the adapter and then set the explicit checkbox to cheched/unchecked when this listener is triggered but this also does not work as i expected, i clicked on the one box and the other one got checked.
So i guess this is a problem with recycled views? Do i have to store the checked Status seperately and restore it every time in the getView method could this be a solution? Or is there an easier way? Please help ;)
So can anybody give me a hint? Thnaks a lot!
--- EDIT ---
So what i now tried to save the status of the checkboxes was to creat a map:
private Map<View, Boolean> itm = new HashMap<View, Boolean>();
and save the status when a box is clicked in in the getView method:
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);
}
Sorry if this is the completely wrong approach in any way but shouldn't this work? The result is the same that the whole list and checked statuses are not correct, what am i doing wrong?
A few off-topic comments:
First you don't need this:
Map<String, String> selectedgroup = new HashMap<String, String>();
You can just do this:
Map<String, String> selectedgroup = (Map<String, String>) list.get(position);
Also, are you sure you need the TextView? The checkbox can hold text too.
About your problems, how do you save which checkbox is checked? You should set the checkbox when returning the view, specially when reusing views.
-- Edit --
Why don't you create a private class like this?
private class ListItem{
String text;
boolean value;
}
And then instead of a List<Map<String,String>>
you could just have a List<ListItem>
.
About the onCheckedChangeListener
, you could iterate of the list using the text from the checkbox to find the correct position and then change the value. If the text is not unique,
instead of using onCheckedChangeListener
, you could use on the ListView a OnItemClickListener
which holds the position of the click.
Okay i think i got it, i used a static id value from the selectedgroup map as the key in the itm map to find the checked/unchecked status of the checkbox. Using the view was the wrong approach because they can't be used as the key.
精彩评论