Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid Limited Multi Select Preference, why no checkmark?
    primarykey
    data
    text
    <p>I'm trying to create a custom preference for an Android application that limits the number of items the user can select. Once the limit is reached the unselected items should be disabled and only the currently selected items are enabled.. If there are less items selected than the limit all items should be enabled.</p> <p>Here are the two classes I've cobbled together. The code runs fine but no the CheckedTextView is not checked. As a result no state is maintained.</p> <p>First the view class...</p> <pre><code>import android.content.Context; import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.ListView; public class LimitedMultiChoiceView extends ListView implements AdapterView.OnItemClickListener { private static final String SEPARATOR = "OV=I=XseparatorX=I=VO"; private static final String LIMITEDSELECTION="limitedSelection"; private static final String SUPERSTATE="superState"; private String mSelection = ""; public LimitedMultiChoiceView(Context context, CharSequence[] items, int limit) { this(context, null, 0, items, limit); } // LimitedMultiChoiceView(Context context) public LimitedMultiChoiceView(Context context, AttributeSet attrs, CharSequence[] items, int limit) { this(context, attrs, 0, items, limit); } // LimitedMultiChoiceView(Context context, AttributeSet attrs) public LimitedMultiChoiceView(Context context, AttributeSet attrs , int defStyle, CharSequence[] items, int limit) { super(context, attrs, defStyle); setAdapter(new ItemAdapter(context, android.R.layout.simple_list_item_multiple_choice, items, limit)); } // LimitedMultiChoiceView(Context context, AttributeSet attrs, int defStyle) public String getSelection() { return mSelection; } // String getSelection() public void onItemClick(AdapterView&lt;?&gt; parent, View child, int position, long id) { // For now we don't need anything... // we think the ItemAdapter manages what we need for each item. } // void onItemClick(AdapterView&lt;?&gt; parent, View child, int position, long id) @Override public void onRestoreInstanceState(Parcelable toParce) { Bundle state=(Bundle)toParce; super.onRestoreInstanceState(state.getParcelable(SUPERSTATE)); mSelection = state.getString(LIMITEDSELECTION); } // void onRestoreInstanceState(Parcelable toParce) @Override public Parcelable onSaveInstanceState() { Bundle state=new Bundle(); state.putParcelable(SUPERSTATE, super.onSaveInstanceState()); state.putString(LIMITEDSELECTION, mSelection); return(state); } // Parcelable onSaveInstanceState() public void setSelection(String value) { mSelection = value; } // void setSelection(String value) class ItemAdapter extends ArrayAdapter&lt;CharSequence&gt; { CharSequence[] mItems = null; int mLimit = 1; public ItemAdapter(Context context, int viewResId, CharSequence[] items, int limit) { super(context, viewResId, items); mItems = items; mLimit = limit; } // ItemAdapter(Context context, int viewResId, CharSequence[] strings, int limit) public boolean areAllItemsEnabled() { // Since we are in a limited selection list not all items can be // selected so this always returns false, there is no calculating // to do. return false; } // boolean areAllItemsEnabled() public boolean isEnabled(int position) { boolean[] clickedIndexes = new boolean[this.getCount()]; boolean result = false; int selectedCount = 0; mSelection = ""; for (int item=0; item &lt; clickedIndexes.length; item++ ) { View itemView = this.getView(item, null, LimitedMultiChoiceView.this); if (itemView instanceof CheckedTextView) { CheckedTextView check = (CheckedTextView)itemView; // First we turn the check mark on or off... if (item == position) { check.setChecked(!check.isChecked()); } // (item == position) // Now we count how many are checked and mark our tracking array if (check.isChecked()) { clickedIndexes[item] = true; mSelection += check.getText() + SEPARATOR; } else { clickedIndexes[item] = false; } // (check.isChecked()) } // (itemView instanceof CheckedTextView) if (clickedIndexes[item]) selectedCount++; } // (int item=0; item&lt; clickedIndexes.length; item++ ) if (selectedCount &gt;= mLimit) { if (clickedIndexes[position]) { result = true; } else { result = false; } // (clickedIndexes[position]) } else { result = true; } // (selectedCount &gt;= mLimit) return result; } // boolean isEnabled(int position) } // class ItemAdapter extends ArrayAdapter&lt;CharSequence&gt; } // class LimitedMultiChoiceView extends ListView </code></pre> <p>This is the preference class...</p> <pre><code>import android.content.Context; import android.preference.ListPreference; import android.util.AttributeSet; import android.view.View; public class ListPreferenceLimitedMultiSelect extends ListPreference { int mLimit = 3; LimitedMultiChoiceView mList = null; String mSelection = ""; public ListPreferenceLimitedMultiSelect(Context context) { this(context, null); } // ListPreferenceLimitedMultiSelect(Context context) public ListPreferenceLimitedMultiSelect(Context context, AttributeSet attr) { super(context, attr); } // ListPreferenceLimitedMultiSelect(Context context, AttributeSet attr) @Override protected void onBindDialogView(View v) { super.onBindDialogView(v); mList.setSelection(mSelection); } // void onBindDialogView(View v) @Override protected View onCreateDialogView() { mList = new LimitedMultiChoiceView(getContext() , this.getEntries(), mLimit); return(mList); } // View onCreateDialogView() @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); if (positiveResult) { if (callChangeListener(mList.getSelection())) { mSelection = mList.getSelection(); persistString(mSelection); } // (callChangeListener(mList.getSelection())) } // (positiveResult) } // void onDialogClosed(boolean positiveResult) @Override protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { mSelection =(restoreValue ? getPersistedString(mSelection) : (String)""); } // void onSetInitialValue(boolean restoreValue, Object defaultValue) } // class ListPreferenceLimitedMultiSelect extends ListPreference </code></pre> <p>Thanks,</p> <p>\ ^ / i l l </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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