Search code examples
javaandroidandroid-sharedpreferences

ListPreference Storing Values as Strings Not Ints


I'm having some trouble understanding how I can save the entry values of a ListPreference as integers. As of now, I have defined my ListPreference as follows:

    <ListPreference
    android:defaultValue="@string/list_preference_sorting_options_default_value"
    android:title="@string/list_preference_sorting_options_title"
    android:key="@string/list_preference_sorting_options_key"
    android:entries="@array/list_preference_sorting_options_entries"
    android:entryValues="@array/list_preference_sorting_options_entry_values"/>

...where the entries and entryValues attributes are defined in the following arrays:

<array name="list_preference_sorting_options_entries">
    <item>@string/list_preference_sorting_options_entry_popularity</item>
    <item>@string/list_preference_sorting_options_entry_top_rated</item>
</array>

<array name="list_preference_sorting_options_entry_values">
    <item>@string/list_preference_sorting_options_entry_value_popularity</item>
    <item>@string/list_preference_sorting_options_entry_value_top_rated</item>
</array>

I understand that I am using String values within the list_preference_sorting_options_entry_values array. However, if I were to define my array in a different way, such as:

<array name="list_preference_sorting_options_entry_values">
    <item>0</item>
    <item>1</item>
</array>

...then within my app, if I try accessing the settings activity, my app crashes.

Furthermore, if I try to read my entry values as ints from SharedPreferences (even though they're stored as Strings) as follows:

int methodFlag = preferences.getInt(getString(R.string.list_preference_sorting_options_key), 0);

...then I receive a Java error that I can't cast a String into an int. In order to properly obtain the entry value as an int, I need to use the getString() method and then parse it into an int:

    String preferenceMethodFlagString = preferences.getString(getString(R.string.list_preference_sorting_options_key),getString(R.string.list_preference_sorting_options_default_value));

    int preferenceMethodFlag = Integer.parseInt(preferenceMethodFlagString);

Is there a way for me to directly store integer values through the arrays.xml? If I use this implementation (with the arrays.xml), will I always have to parse the String into an int?

I've seen other SO questions where if the SharedPreferences.Editor is used, integer values will be stored into the ListPreference's entry values. Is this the only means to store integer values?


Solution

  • ListPreference has been designed such that it can only hold string values.

    Member variables of ListPreference are as follows

    private CharSequence[] mEntries;
    private CharSequence[] mEntryValues;
    private String mValue;
    private String mSummary;
    

    Further, values are read retrieved as

    mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
    mEntryValues = a.getTextArray(com.android.internal.R.styleable.ListPreference_entryValues);
    

    getTextArray() looks for string-arrays resource ids only.

    Hence, entries and entryValues should always be string resource.

    If you want to use int values,

    <string-array name="entries_list_preference">
        <item>0</item> <!-- This does not make it int, it will be stored as string only -->
        <item>1</item>
        <item>2</item>
    </string-array>
    
    <string-array name="entryvalues_list_preference">
        <item>0</item>
        <item>1</item>
        <item>2</item>
    </string-array>
    

    When you are reading its value, parse it as integer.

    ListPreference listPreference = (ListPreference) findPreference ("list_preference");
    String value = listPreference.getValue();
    if(!TextUtils.isEmpty(value))
        performAction(Integer.parseInt(listPreference.getValue()));
    

    Now you can write performAction(int type) method as per your requirements.