2010-09-15 11 views
49

Używając prostego EditTextPreference w mojej działalności preferencje:PreferenceActivity: zapisać wartość jako liczba całkowita

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

Czy istnieje sposób, że wartość ta konfiguracja będzie zapisany jako liczba całkowita? Teraz wydaje się, że tylko pozwala na wprowadzanie cyfr, ale wartość ta jest jeszcze zapisany jako ciąg:

numerem:

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

rzuca mi java.lang.ClassCastException: java.lang.String oraz:

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

pobiera wartość pomyślnie.

Jak ustawić PreferenceActivity, aby domyślnie zapisać wartość jako liczbę całkowitą?

Odpowiedz

58

Można przedłużyć 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)); 
    } 
} 

Byłoby lepiej, aby zastąpić onSetInitialValue() i setText() metody, ale wtedy trzeba by skopiować część kodu z klasy bazowej. Powyższe rozwiązanie jest prostsze, ale jest dość trudne - metody "łańcuchowe" robią coś z ints. Staraj się nie przedłużać tej klasy dalszy ;-)

Można go używać z XML przez:

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

@Brutall, chciałbym podziękować za ulepszenie kodu. Ale ktoś powiedział mi, że nowy kod jest ... zbyt długi, a on go odrzucił. Och, ale co robią ludzie, jeśli stary kod jest zły i trzeba go wymienić, ale nie robią tego, ponieważ nowy jest ... długi? Nawet jeśli jest lepiej. O, mój, to WIELKI! To jest miejsce dla programistów? Mam kilka projektów open source i otwieram wszelkie zmiany w moim kodzie. Jak mu wstyd! W każdym razie, dziękuję bardzo, Brutall. –

+0

Btw, wszystko co robię to: ustawić typ wejścia na numer; dodaj 'TextWatcher', aby upewnić się, że użytkownik tekstu nie jest pusty, a domyślną wartością jest' 0'. –

+3

im wystąpienie błędu runtime na 'return String.valueOf (getPersistedInt (-1));', nie może rozpocząć działalność z powodu tej linii – ibaguio

7

Nawet jeśli ustawisz android: numeric = "integer", będzie to preferencja tekstowa - jak sugeruje jego nazwa. Możesz łatwo przekonwertować wartość ciągu na int używając Integer.valueOf(). Możesz również zastąpić PreferenceActivity, aby automatycznie konwertować przy wyjściu.


Myślę, że najlepszym rozwiązaniem jest, aby napisać prostą metodę, aby uzyskać tę wartość z preferencjami. Coś takiego:

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

Wtedy można bardzo łatwo użyć go z kodu.

+0

Gdzie mogę to zmienić?Domyślnie funkcja "PreferenceActivity" automatycznie zapisuje zmiany, czy powinienem zastąpić niektóre metody uzyskiwania wartości lub zamiast tego robić wszystkie oszczędności? – Laimoncijus

+0

OK, zmiana preferencji nie jest dobra, ponieważ mogą wystąpić problemy z ClassCastException. Zaktualizowałem swoją odpowiedź. – broot

+0

Tak, sam myślałem o pakowniku, ale nadal nie lubię tego rozwiązania ... 'SharedPreferences' ma już metodę' getInt', więc wciąż mam nadzieję, że uda się znaleźć sposób, aby powiedzieć "PreferenceActivity", aby zapisać wartość jak int - cała funkcjonalność jest tam ... po prostu nie działa tak jak chciał ... – Laimoncijus

0

miałem ten sam problem. (Chciałem, aby SharedPreference dało mi numer portu, który zapisałem w pliku xml preferencji jako defaultValue).

Wdrożenie wszystkich metod SharedPreferences wymagałoby wiele wysiłku, więc napisanie niestandardowej metody w klasie instancji SharedPreferences sugerowałoby, że najlepiej byłoby zasugerować broot.

Można aswell prostu użyć statycznej metody Integer w wierszu, w którym jest to potrzebne:

int number = Integer.valueOf(settings.getString("myNumberString", "0")); 
3

Chociaż odpowiedź został zaparkowany akceptowane Chciałbym podzielić się jeszcze jedną krótszą drogę do osiągnięcia tego celu:

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

Ponieważ już ustawiono, że można wprowadzać tylko liczby, nie nastąpi to z powodu żadnego wyjątku. jeszcze do uzupełnienia mojej odpowiedzi:

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