ListPreference: use string-array as Entry and integer-array as Entry values ​​do not work

I use ListPreference in settings.xml file. I want to show the user a list of 3 possible options. When the user selects one of the parameters in the settings, I get this error:

java.lang.NullPointerException at android.preference.ListPreference.onDialogClosed(ListPreference.java:264) at android.preference.DialogPreference.onDismiss(DialogPreference.java:381) at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1228) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4424) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) 

This is the ListPreference code:

 <ListPreference android:entries="@array/date_alignement" android:entryValues="@array/date_alignement_values" android:key="settings_date_alignement" android:summary="@string/settings_date_alignement_summary" android:title="@string/settings_date_alignement_title" /> 

And here are the arrays that I use to populate the records:

 <string-array name="date_alignement"> <item>"Top"</item> <item>"Center"</item> <item>"Bottom"</item> </string-array> <integer-array name="date_alignement_values"> <item >0</item> <item >1</item> <item >2</item> </integer-array> 

In my onSharedPreferenceChanged, I use these values ​​as follows:

 @Override public void onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key) { //Text mAlignment = mPrefs.getInt(PREF_ALIGNMENT, 1); switch (mAlignment) { case 0: offsetY = mHeight/3.0f; break; case 2: offsetY = mHeight*2.0f/3.0f; break; default: offsetY = mHeight/2.0f; break; } } 

If I use another string array for entryValues, it works. For example, if I use the same array of strings as the values ​​and records:

  android:entries="@array/date_alignement" android:entryValues="@array/date_alignement" 

then I need to change the code a bit, but it works:

  if(mAlignment.equalsIgnoreCase("center")) { offsetY = mHeight/2.0f; } else if(mAlignment.equalsIgnoreCase("top")) { offsetY = mHeight/3.0f; } else if(mAlignment.equalsIgnoreCase("bottom")) { offsetY = mHeight*2.0f/3.0f; } 

Why can't I use a string array and an integer array for records and ListPreference values?

+68
android listpreference
Jul 05 2018-12-12T00:
source share
4 answers

The answer is simple: because Android is designed that way. It just uses String arrays for both records and input values ​​and for everyone. And I don't see any problem with this fact, since you can easily convert String to int using the Integer.parseInt() method. Hope this helps.

+81
Jul 05 2018-12-15T00:
source share

The answer is listed on the Preferred Documentation List .

 int findIndexOfValue (String value) 

will return an index for the given value and the argument will be accepted as String, so the entryValues ​​array must be an array of strings to get this working.

+3
Nov 22 '16 at 15:39
source share

You can convert ListPreference values ​​to strings to preserve ListPreference and then convert them back when accessing the persistent data store.

  1. When setting input values, use strings instead of integers: "1", "2", "3" etc.
  2. Create a custom IntListPreference which stores the values ​​as integers
  3. In your preferences.xml file change <ListPreference> to <your.app.package.IntListPreference>

IntListPreference.java

Here is an example implementation. Tested and works on AndroidX Preference 1.0.0.

 public class IntListPreference extends ListPreference { public IntListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public IntListPreference(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public IntListPreference(Context context, AttributeSet attrs) { super(context, attrs); } public IntListPreference(Context context) { super(context); } @Override protected boolean persistString(String value) { int intValue = Integer.parseInt(value); return persistInt(intValue); } @Override protected String getPersistedString(String defaultReturnValue) { int intValue; if (defaultReturnValue != null) { int intDefaultReturnValue = Integer.parseInt(defaultReturnValue); intValue = getPersistedInt(intDefaultReturnValue); } else { // We haven't been given a default return value, but we need to specify one when retrieving the value if (getPersistedInt(0) == getPersistedInt(1)) { // The default value is being ignored, so we're good to go intValue = getPersistedInt(0); } else { throw new IllegalArgumentException("Cannot get an int without a default return value"); } } return Integer.toString(intValue); } } 
0
Apr 27 '19 at 0:03
source share

The following worked for me:

 String objectName = prefs.getString("listPrefMelodyYd1", ""); switch (objectName.toUpperCase()) { case "1": playSound(catSound); break; case "2": playSound(dogSound); break; case "3": playSound(cowSound); break; } 
-5
Dec 25 '17 at 12:12
source share



All Articles