Note that there are some explanatory texts on larger screens.

plurals
  1. PORefreshing checkbox state in a listview
    text
    copied!<p>I have list view with custom row layout (list_row.xml) that contains CheckBox element:</p> <pre><code>&lt;TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" android:weightSum="1.0"&gt; &lt;TableRow&gt; &lt;TextView android:id="@+id/name" android:layout_weight=".85" android:layout_width="0dip" android:layout_height="wrap_content" android:text="sample" android:textSize="24sp"&gt; &lt;/TextView&gt; &lt;CheckBox android:id="@+id/enabled" android:layout_weight=".15" android:layout_width="0dip" android:layout_height="wrap_content" android:focusable="false"&gt; &lt;/CheckBox&gt; &lt;/TableRow&gt; &lt;/TableLayout&gt; </code></pre> <p>In my list activity I've got ListRowAdapter:</p> <pre><code>private static class ListRowAdapter extends ArrayAdapter&lt;ListRow&gt; implements CompoundButton.OnCheckedChangeListener { private List&lt;ListRow&gt; items; private LayoutInflater vi; private SparseBooleanArray mCheckStates; public ListRowAdapter(Context context, int textViewResourceId, List&lt;ListRow&gt; objects) { super(context, textViewResourceId, objects); this.items = objects; this.vi = LayoutInflater.from(context); this.mCheckStates = new SparseBooleanArray(objects.size()); for(int i=0;i&lt;mCheckStates.size();i++){ mCheckStates.put(i,items.get(i).isEnabled()); } Log.i("VIEW", "constructor"); } public boolean isChecked(int position) { return mCheckStates.get(position, false); } public void setChecked(int position, boolean isChecked) { mCheckStates.put(position, isChecked); items.get(position).setEnabled(isChecked); notifyDataSetChanged(); } public void toggle(int position) { setChecked(position, !isChecked(position)); } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ListRow r = (ListRow) buttonView.getTag(); r.setEnabled(isChecked); mCheckStates.put(items.indexOf(r), isChecked); Toast.makeText(getContext(), "row " + r.getName() + " changed to "+isChecked, Toast.LENGTH_SHORT).show(); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { Log.i("VIEW", "init holder"); convertView = vi.inflate(R.layout.list_row, null); holder = new ViewHolder(); holder.name = (TextView) convertView.findViewById(R.id.name); holder.enabled = (CheckBox) convertView .findViewById(R.id.enabled); convertView.setTag(holder); } else { Log.i("VIEW", "using holder"); holder = (ViewHolder) convertView.getTag(); } ListRow row = items.get(position); if (row != null) { holder.name.setText(row.getName()); holder.enabled.setTag(row); holder.enabled.setChecked(mCheckStates.get(position, false)); holder.enabled.setOnCheckedChangeListener(this); } return convertView; } static class ViewHolder { TextView name; CheckBox enabled; } } </code></pre> <p>In my Activity (that extends ListActivity) I do the following:</p> <pre><code>private static List&lt;ListRow&gt; rows; private ListRowAdapter lra; </code></pre> <p>... and then</p> <pre><code>getListView().setItemsCanFocus(false); getListView().setTextFilterEnabled(true); rows = initRows(); lra = new ListRowAdapter(this, R.layout.list_row, rows); setListAdapter(lra); </code></pre> <p>and that works fine while scrolling. But if I don't use <code>mCheckStates</code> array it fails! I just can't understand why. I have items array as a member of my Activity class and it contains all the states of checkboxes! I update it in <code>onCheckedChanged()</code> method like I update <code>mCheckState</code>. So the following code has to work:</p> <pre><code>public boolean isChecked(int position) { return items.get(position).isEnebled(); } public void setChecked(int position, boolean isChecked) { items.get(position).setEnabled(isChecked); notifyDataSetChanged(); } public void toggle(int position) { setChecked(position, !isChecked(position)); } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ListRow r = (ListRow) buttonView.getTag(); r.setEnabled(isChecked); Toast.makeText(getContext(), "row " + r.getName() + " changed to "+isChecked, Toast.LENGTH_SHORT).show(); } </code></pre> <p>and in <code>getView()</code> method:</p> <pre><code>holder.enabled.setTag(row);holder.enabled.setChecked(row.isEnabled()); </code></pre> <p>But it doesn't. It loses checkbox states while scrolling and I don't know why.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload