Получение целых или индексных значений из предпочтений списка

Я создаю списки с общим предпочтением, и когда вызывается метод onPreferenceChanged (), я хочу в некоторых случаях извлечь индекс элемента в списке или целочисленное значение. Я пытаюсь создать XML-данные следующим образом:

В массивах:

<string-array name="BackgroundChoices"> <item>Dark Background</item> <item>Light Background</item> </string-array> <array name="BackgroundValues"> <item>1</item> <item>0</item> </array> <string-array name="SpeedChoices"> <item>Slow</item> <item>Medium</item> <item>Fast</item> </string-array> <array name="SpeedValues"> <item>1</item> <item>4</item> <item>16</item> </array> 

В файле настроек xml:

 <PreferenceScreen android:key="Settings" xmlns:android="http://schemas.android.com/apk/res/android" android:title="Settings"> <ListPreference android:key="keyBackground" android:entries="@array/BackgroundChoices" android:summary="Select a light or dark background." android:title="Light or Dark Background" android:positiveButtonText="Okay" android:entryValues="@array/BackgroundValues"/> <ListPreference android:key="keySpeed" android:entries="@array/SpeedChoices" android:summary="Select animation speed." android:title="Speed" android:entryValues="@array/SpeedValues"/> </PreferenceScreen> 

Так что мой xml не работает. Я знаю, как это сделать, используя строковый массив, а не массив для значений. И я мог бы вытащить строки значений и получить то, что хочу от этого, но я бы предпочел (если возможно) иметь списки, в которых значения были ints, booleans или перечисления. Каков обычный способ сделать это?

заранее спасибо,

сойка

Поместите предпочтения в String и используйте Integer.parseInt() . Я думаю, что есть отчет об ошибке, на который вы ссылаетесь, но я не могу найти ссылку. Из опыта я могу сказать вам просто использовать Strings и сэкономить себе много разочарования.

Обратите внимание на других пользователей SO, если вы можете доказать свою неправоту, я приветствую это.

Андрей был прав, нить здесь :

Он все еще комментируется, и все же никаких изменений (по 2.3.3 в любом случае).

Integer.parseInt () .valueOf () должен работать. Если функция valueOf () работает без ошибок, используйте ее, поскольку она не выделяет столько, сколько имеет значение parseInt (), когда вам нужно избегать GC, как я.

Основываясь на ListPreference Android, я создал IntListPreference . Использование является straighforward – просто поместите этот фрагмент в свои предпочтения xml:

 <org.bogus.android.IntListPreference android:key="limitCacheLogs" android:defaultValue="20" android:entries="@array/pref_download_logs_count_titles" android:entryValues="@array/pref_download_logs_count_values" android:negativeButtonText="@null" android:positiveButtonText="@null" android:title="@string/pref_download_logs_count" /> 

И что в strings.xml

 <string name="pref_download_logs_count">Number of logs per cache</string> <string-array name="pref_download_logs_count_titles"> <item>10</item> <item>20</item> <item>50</item> <item>Give me all!</item> </string-array> <integer-array name="pref_download_logs_count_values"> <item>10</item> <item>20</item> <item>50</item> <item>-1</item> </integer-array> 

Вот класс ListIntegerPreference я использую (написанный для com.android.support:preference-v7:24.0.0 ). Он перезаписывает несколько методов и конвертирует между Integer и String где это возможно, так что базовый ListPreference не распознает, что вы работаете с ListPreference а не с Strings .

 public class ListIntegerPreference extends ListPreference { public ListIntegerPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public ListIntegerPreference(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public ListIntegerPreference(Context context, AttributeSet attrs) { super(context, attrs); } public ListIntegerPreference(Context context) { super(context); } @Override protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { int defValue = defaultValue != null ? Integer.parseInt((String)defaultValue) : 0; int value = getValue() == null ? 0 : Integer.parseInt(getValue()); this.setValue(String.valueOf(restoreValue ? this.getPersistedInt(value) : defValue)); } @Override public void setValue(String value) { try { Field mValueField = ListPreference.class.getDeclaredField("mValue"); mValueField.setAccessible(true); Field mValueSetField = ListPreference.class.getDeclaredField("mValueSet"); mValueSetField.setAccessible(true); String mValue = (String)mValueField.get(this); boolean mValueSet = (boolean)mValueSetField.get(this); boolean changed = !TextUtils.equals(mValue, value); if(changed || !mValueSet) { mValueField.set(this, value); mValueSetField.set(this, mValueSet); this.persistInt(Integer.parseInt(value)); if(changed) { this.notifyChanged(); } } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } 

Я использую это, создавая значения ListPreferences через код, просто попробуйте. Это может сработать сразу, или, возможно, вам нужно переопределить дополнительные функции. Если это так, это хороший старт и показывает, как вы можете это сделать …