Пример MultiSelectListPreference

Я с трудом пытаюсь найти хороший пример MultiSelectListPreference, предоставляемый в Android API. Я видел много ссылок на этот блог , и, поскольку это конечный результат, которого я хочу, я не хочу создавать класс для каждого выбора с несколькими избранными, которые я хочу реализовать. В конечном счете, я хочу увидеть предпочтения xml для простого диалога с несколькими выборами (который я буду заполнять значениями динамически), а также для вызова addPreferencesFromResource(R.xml.preferences);

В настоящее время у меня есть:

 <MultiSelectListPreference android:defaultValue="" android:enabled="true" android:entries="@array/pref_default_entries" android:entryValues="@array/pref_default_values" android:key="TargetList" android:persistent="true" android:summary="@string/TargetSummary" android:title="@string/TargetTitle" /> 

И когда я пытаюсь вызвать addPreferencesFromResource в моем вызове onCreate, я получаю следующую ошибку:

 06-18 13:59:30.690: E/AndroidRuntime(6052): FATAL EXCEPTION: main 06-18 13:59:30.690: E/AndroidRuntime(6052): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tracker/com.tracker.TrackerActivity}: android.view.InflateException: Binary XML file line #37: Error inflating class java.lang.reflect.Constructor 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1818) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1834) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.ActivityThread.access$500(ActivityThread.java:122) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1027) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.os.Handler.dispatchMessage(Handler.java:99) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.os.Looper.loop(Looper.java:132) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.ActivityThread.main(ActivityThread.java:4126) 06-18 13:59:30.690: E/AndroidRuntime(6052): at java.lang.reflect.Method.invokeNative(Native Method) 06-18 13:59:30.690: E/AndroidRuntime(6052): at java.lang.reflect.Method.invoke(Method.java:491) 06-18 13:59:30.690: E/AndroidRuntime(6052): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) 06-18 13:59:30.690: E/AndroidRuntime(6052): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) 06-18 13:59:30.690: E/AndroidRuntime(6052): at dalvik.system.NativeStart.main(Native Method) 06-18 13:59:30.690: E/AndroidRuntime(6052): Caused by: android.view.InflateException: Binary XML file line #37: Error inflating class java.lang.reflect.Constructor 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.createItem(GenericInflater.java:397) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.onCreateItem(GenericInflater.java:417) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:428) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.rInflate(GenericInflater.java:481) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.inflate(GenericInflater.java:326) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.inflate(GenericInflater.java:263) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:269) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.PreferenceActivity.addPreferencesFromResource(PreferenceActivity.java:1366) 06-18 13:59:30.690: E/AndroidRuntime(6052): at com.tracker.TrackerActivity.onCreate(TrackerActivity.java:30) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1050) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1782) 06-18 13:59:30.690: E/AndroidRuntime(6052): ... 11 more 06-18 13:59:30.690: E/AndroidRuntime(6052): Caused by: java.lang.reflect.InvocationTargetException 06-18 13:59:30.690: E/AndroidRuntime(6052): at java.lang.reflect.Constructor.constructNative(Native Method) 06-18 13:59:30.690: E/AndroidRuntime(6052): at java.lang.reflect.Constructor.newInstance(Constructor.java:416) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.GenericInflater.createItem(GenericInflater.java:383) 06-18 13:59:30.690: E/AndroidRuntime(6052): ... 21 more 06-18 13:59:30.690: E/AndroidRuntime(6052): Caused by: java.lang.NullPointerException 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.content.res.AssetManager.getResourceTextArray(AssetManager.java:215) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.content.res.Resources.getTextArray(Resources.java:435) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.content.res.TypedArray.getTextArray(TypedArray.java:628) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.MultiSelectListPreference.onGetDefaultValue(MultiSelectListPreference.java:210) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.Preference.<init>(Preference.java:257) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.DialogPreference.<init>(DialogPreference.java:69) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.DialogPreference.<init>(DialogPreference.java:90) 06-18 13:59:30.690: E/AndroidRuntime(6052): at android.preference.MultiSelectListPreference.<init>(MultiSelectListPreference.java:49) 06-18 13:59:30.690: E/AndroidRuntime(6052): ... 24 more 

Я с нетерпением жду вашего ответа!

Solutions Collecting From Web of "Пример MultiSelectListPreference"

Сигрист прав, чтобы решить начальную ошибку, которую вы видите. Для этого необходимы значения по умолчанию, даже если они пустые. Это помогло мне в том, что я хочу предоставлять ценности в RUNTIME , но не вмешиваться в полную реализацию.

См. Этот код для того, как я предоставляю значения во время выполнения, не требуя полной реализации.

 public class CalendarListPreference extends MultiSelectListPreference { ContentResolver cr; Cursor cursor; String[] projection = new String[] {CalendarContract.Calendars.NAME, CalendarContract.Calendars.CALENDAR_DISPLAY_NAME}; String selection = "(" + CalendarContract.Calendars.VISIBLE + " = ?)"; String[] selectionArgs = new String[] { "1" }; public CalendarListPreference(Context context, AttributeSet attrs) { super(context, attrs); List<CharSequence> entries = new ArrayList<CharSequence>(); List<CharSequence> entriesValues = new ArrayList<CharSequence>(); cr = context.getContentResolver(); cursor = cr.query(CalendarContract.Calendars.CONTENT_URI, projection, selection, selectionArgs, null); while (cursor.moveToNext()) { String name = cursor.getString(0); String displayName = cursor.getString(1); entries.add(name); entriesValues.add(displayName); } setEntries(entries.toArray(new CharSequence[]{})); setEntryValues(entriesValues.toArray(new CharSequence[]{})); } } 

В моем strings.xml

 <string-array name="pref_calendar_list_default"> </string-array> 

В моих предпочтениях.xml

 <com.mynameistodd.autovolume.CalendarListPreference android:defaultValue="@array/pref_calendar_list_default" android:key="@string/pref_calendar_list_key" android:summary="@string/pref_calendar_list_summary" android:title="@string/pref_calendar_list_title" android:dependency="@string/pref_calendar_enabled_key"/> 

Я знаю, что это старый вопрос, но мне это помогло, вот и мой ответ!

Необходимо указать свойство defaultValues

 <MultiSelectListPreference android:dialogTitle="@string/mode_repeat" android:key="mode_repeat" android:summary="" android:title="@string/mode_repeat" android:entries="@array/weekdays" android:entryValues="@array/weekdays_values" android:defaultValue="@array/empty_array" /> 

Если вам не нужны значения по умолчанию, создайте пустой массив в файле strings.xml

 <string-array name="empty_array"/> 

Я создал MultiSelectListPreference для устройств под управлением Android в API раньше уровня 11.

  • Поддерживает список изменений ListListener для выбранных значений.
  • Поддерживает автоматическую настройку сводки.
  • Примеры прилагаются.

https://gist.github.com/cardil/4754571

 package pl.wavesoftware.widget; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnMultiChoiceClickListener; import android.content.res.TypedArray; import android.preference.ListPreference; import android.util.AttributeSet; public class MultiSelectListPreference extends ListPreference { private String separator; private static final String DEFAULT_SEPARATOR = "\u0001\u0007\u001D\u0007\u0001"; private boolean[] entryChecked; public MultiSelectListPreference(Context context, AttributeSet attributeSet) { super(context, attributeSet); entryChecked = new boolean[getEntries().length]; separator = DEFAULT_SEPARATOR; } public MultiSelectListPreference(Context context) { this(context, null); } @Override protected void onPrepareDialogBuilder(Builder builder) { CharSequence[] entries = getEntries(); CharSequence[] entryValues = getEntryValues(); if (entries == null || entryValues == null || entries.length != entryValues.length) { throw new IllegalStateException( "MultiSelectListPreference requires an entries array and an entryValues " + "array which are both the same length"); } restoreCheckedEntries(); OnMultiChoiceClickListener listener = new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int which, boolean val) { entryChecked[which] = val; } }; builder.setMultiChoiceItems(entries, entryChecked, listener); } private CharSequence[] unpack(CharSequence val) { if (val == null || "".equals(val)) { return new CharSequence[0]; } else { return ((String) val).split(separator); } } /** * Gets the entries values that are selected * * @return the selected entries values */ public CharSequence[] getCheckedValues() { return unpack(getValue()); } private void restoreCheckedEntries() { CharSequence[] entryValues = getEntryValues(); // Explode the string read in sharedpreferences CharSequence[] vals = unpack(getValue()); if (vals != null) { List<CharSequence> valuesList = Arrays.asList(vals); for (int i = 0; i < entryValues.length; i++) { CharSequence entry = entryValues[i]; entryChecked[i] = valuesList.contains(entry); } } } @Override protected void onDialogClosed(boolean positiveResult) { List<CharSequence> values = new ArrayList<CharSequence>(); CharSequence[] entryValues = getEntryValues(); if (positiveResult && entryValues != null) { for (int i = 0; i < entryValues.length; i++) { if (entryChecked[i] == true) { String val = (String) entryValues[i]; values.add(val); } } String value = join(values, separator); setSummary(prepareSummary(values)); setValueAndEvent(value); } } private void setValueAndEvent(String value) { if (callChangeListener(unpack(value))) { setValue(value); } } private CharSequence prepareSummary(List<CharSequence> joined) { List<String> titles = new ArrayList<String>(); CharSequence[] entryTitle = getEntries(); CharSequence[] entryValues = getEntryValues(); int ix = 0; for (CharSequence value : entryValues) { if (joined.contains(value)) { titles.add((String) entryTitle[ix]); } ix += 1; } return join(titles, ", "); } @Override protected Object onGetDefaultValue(TypedArray typedArray, int index) { return typedArray.getTextArray(index); } @Override protected void onSetInitialValue(boolean restoreValue, Object rawDefaultValue) { String value = null; CharSequence[] defaultValue; if (rawDefaultValue == null) { defaultValue = new CharSequence[0]; } else { defaultValue = (CharSequence[]) rawDefaultValue; } List<CharSequence> joined = Arrays.asList(defaultValue); String joinedDefaultValue = join(joined, separator); if (restoreValue) { value = getPersistedString(joinedDefaultValue); } else { value = joinedDefaultValue; } setSummary(prepareSummary(Arrays.asList(unpack(value)))); setValueAndEvent(value); } /** * Joins array of object to single string by separator * * Credits to kurellajunior on this post * http://snippets.dzone.com/posts/show/91 * * @param iterable * any kind of iterable ex.: <code>["a", "b", "c"]</code> * @param separator * separetes entries ex.: <code>","</code> * @return joined string ex.: <code>"a,b,c"</code> */ protected static String join(Iterable<?> iterable, String separator) { Iterator<?> oIter; if (iterable == null || (!(oIter = iterable.iterator()).hasNext())) return ""; StringBuilder oBuilder = new StringBuilder(String.valueOf(oIter.next())); while (oIter.hasNext()) oBuilder.append(separator).append(oIter.next()); return oBuilder.toString(); } }