Tuesday, April 17, 2012

PreferenceActivity: save value as integer


Using a simple EditTextPreference in my preferences activity:




<EditTextPreference
android:key="SomeKey"
android:title="@string/some_title"
android:summary="..."
android:numeric="integer"
android:maxLength="2"
/>



Is there a way that this configuration value would be saved as integer? Seems now it just allows to enter numbers, but the value is still saved as string:



Calling:




SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int value = preferences.getInt("SomeKey", -1);



throws me java.lang.ClassCastException: java.lang.String , and:




SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String value = preferences.getString("SomeKey", "-1");



retrieves the value successfully.



How to make PreferenceActivity to save value as integer by default?


Source: Tips4all

2 comments:

  1. You could extend EditTextPreference:

    public class IntEditTextPreference extends EditTextPreference {

    public IntEditTextPreference(Context context) {
    super(context);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs) {
    super(context, attrs);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    }

    @Override
    protected String getPersistedString(String defaultReturnValue) {
    return String.valueOf(getPersistedInt(-1));
    }

    @Override
    protected boolean persistString(String value) {
    return persistInt(Integer.valueOf(value));
    }
    }


    It would be better to overwrite onSetInitialValue() and setText() methods, but then you would have to copy some code from a base class. Above solution is simplier, but it's quite tricky - "string" methods do something with ints. Try to not extend this class further ;-)

    You could use it from XML by:

    <package.name.IntEditTextPreference
    android:key="SomeKey"
    android:title="@string/some_title"
    android:summary="..."
    android:numeric="integer"
    android:maxLength="2"
    />


    Tested, works :-)

    ReplyDelete
  2. Even if you set android:numeric="integer" it'll be text preference - as its name suggest. You could easily convert string value to int using Integer.valueOf(). Also you could overwrite PreferenceActivity to do conversion automatically on exit.



    I think the best solution is to write simple method to get this value from preferences. Something like:

    public static int getSomePref(Context context) {
    SharedPreferences prefs =
    PreferenceManager.getDefaultSharedPreferences(context);
    String value = prefs.getString("SomeKey", null);
    return value == null ? -1 : Integer.valueOf(value);
    }


    Then you could very easily use it from your code.

    ReplyDelete