Dania
Dania

Reputation: 67

ListPreference Entry is being retrived as index instead of a its string value

I am trying to make an application which will forecast the weather data in the next 7 days. I am adding a settings activity in which the user can change the temperature unit to either Fahrenheit or metric.

I have define this as a ListPreference with entries taken from an array with values metric and Fahrenheit as the following,

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
<!--location preference:-->
    <EditTextPreference
        android:key="@string/pref_location_key"
        android:title="@string/locTitle"
        android:defaultValue="@string/pref_location_default"
        android:inputType="text"
        android:singleLine="true"
        android:summary="enter location"/>



    <!--temperature unit preference:-->

 <ListPreference android:key="@string/pref_units_key"
                 android:defaultValue="@string/pref_units_metric"
                 android:title="Temperature Unit"
                 android:summary="select a temperature unit"
                 android:entries="@array/units"
                 android:entryValues="@array/indx"/>




</PreferenceScreen>

This is the array resource that contains the entries with the indices of these entries,

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string-array name="units">

        <item>metric</item>
        <item>Fahrenheit</item>

    </string-array>

    <string-array name="indx">
        <item>0</item>
        <item>1</item>

    </string-array>


</resources>

The problem is that when the temperature preference changes what gets stored in the preference variable is the index string value (either "0" or "1") not the entry index value which is Fahrenheit or metric. When I try to check for the units using if statement the app doesn't recognize the units value unless I use the index string instead of the entry string,

Here is where I try to check the unit,

private String formatHighLows(double high, double low, String unitType) {

        if (unitType.equalsIgnoreCase(getString(R.string.pref_units_imperial))) {
            high = (high * 1.8) + 32;
            low = (low * 1.8) + 32;
        } else if (!unitType.equals(getString(R.string.pref_units_metric))) {
            Log.d(LOG_TAG, "Unit type not found: " + unitType);
        }

        // For presentation, assume the user doesn't care about tenths of a degree.
        long roundedHigh = Math.round(high);
        long roundedLow = Math.round(low);

        String highLowStr = roundedHigh + "/" + roundedLow;
        return highLowStr;
    }

pref_units_imperial contains the string Fahrenheit, but this if statement is not recognized unless it is written as

if (unitType.equalsIgnoreCase ("1")), unitType has been fetched from the shared preferences previously and sent to the method. 

Here is the settings class I use,

public class SettingsActivity extends PreferenceActivity
        implements Preference.OnPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
// Add 'general' preferences, defined in the XML file
// TODO: Add preferences from XML
   addPreferencesFromResource(R.xml.pref_general);
   bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));

        bindPreferenceSummaryToValue(findPreference (getString(R.string.pref_units_key))); //this will find the preference value associated with locKey key and pass it to be saved in the shared preferences

    //we are just getting a reference to the preference, we are not fetching any data from it.


    }

    private void bindPreferenceSummaryToValue(Preference preference) { //receives user preference
// Set the listener to watch for value changes.
        preference.setOnPreferenceChangeListener(this);

// Trigger the listener immediately with the preference's
// current value.
        onPreferenceChange(preference,
                PreferenceManager
                        .getDefaultSharedPreferences(preference.getContext()) //conetxt from which this is called. (returns all shared preferences in the app, so you need to distinguish
                        .getString(preference.getKey(), "")); //the key of the setting that has been changed
    }
    @Override
    public boolean onPreferenceChange(Preference preference, Object value) {
        String stringValue = value.toString();

        if (preference instanceof ListPreference) {
            // For list preferences, look up the correct display value in
            // the preference's 'entries' list (since they have separate labels/values).
            ListPreference listPreference = (ListPreference) preference;
            int prefIndex = listPreference.findIndexOfValue(stringValue);
            if (prefIndex >= 0) {
                preference.setSummary(listPreference.getEntries()[prefIndex]); //get the entries we have specified in the array xml by the indices associated with them
            }
        } else {
            // For other preferences, set the summary to the value's simple string representation.
            preference.setSummary(stringValue);
        }
        return true;
    }
}

In this line preference.setSummary(listPreference.getEntries()[prefIndex], it is supposed to get either Fahrenheit or metric, but it seems that it is getting "0" or "1", I want to get the string name of the unit, I've tried to debug the app, but I couldn't know why it is assigning the index value instead of the entry.

Can anyone please help me fixing this problem?

Any help is appreciated.

Thank you.

Upvotes: 2

Views: 1004

Answers (0)

Related Questions