2010-09-15 18 views
49

Usando un simple EditTextPreference en mi actividad preferencias:PreferenceActivity: guardar el valor como número entero

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

¿Hay alguna manera de que este valor de configuración se guarda como número entero? Ahora parece que sólo permite introducir números, pero el valor todavía se guarda como cadena:

Calling:

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

me tira java.lang.ClassCastException: java.lang.String, y:

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

recupera el valor éxito.

Cómo hacer que PreferenceActivity guarde el valor como número entero de forma predeterminada?

Respuesta

58

Se podría extender 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)); 
    } 
} 

Sería mejor para sobrescribir onSetInitialValue() y setText() métodos, pero entonces tendría que copiar un código de una clase base. La solución anterior es más simple, pero es bastante complicada: los métodos de "cadena" hacen algo con los enteros. Trate de no extender esta clase adicional ;-)

Se puede usar desde XML por:

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

@Brutall, me gustaría agradecerle por mejorar el código. Pero alguien me dijo que el nuevo código es ... demasiado largo, y él lo rechazó. Ah, pero ¿qué hace la gente si el código anterior es malo y necesita ser reemplazado, pero no lo hacen porque el nuevo es ... largo? Incluso si es mejor Oh mi, eso es genial! Este es lugar para programadores? Tengo algunos proyectos de código abierto, y estoy abriendo para cualquier cambio en mi código. ¡Qué vergüenza para él! De todos modos, muchas gracias, Brutall. –

+0

Por cierto, todo lo que hago es: establecer el tipo de entrada al número; agregue un 'TextWatcher', para asegurarse de que el texto que ingresa no esté vacío, y el valor predeterminado es' 0'. –

+3

Estoy obteniendo un error de tiempo de ejecución en 'return String.valueOf (getPersistedInt (-1));', no se puede iniciar la actividad debido a esa línea – ibaguio

7

Incluso si establece android: numeric = "integer", será preferencia de texto, como su nombre lo sugiere. Puede convertir fácilmente el valor de cadena a int usando Integer.valueOf(). También podría sobreescribir PreferenceActivity para realizar la conversión automáticamente al salir.


creo que la mejor solución es escribir método sencillo para obtener este valor de las preferencias. Algo como:

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

Entonces podría usarlo fácilmente desde su código.

+0

¿Dónde puedo anular esto?Por defecto 'PreferenceActivity' hace el guardado automáticamente, ¿debo anular algún método para obtener el valor o hacer todo en mi lugar? – Laimoncijus

+0

Ok, cambiar el tipo de preferencia no es bueno, porque puede que tenga problemas con ClassCastException. He actualizado mi respuesta. – broot

+0

Sí, pensé en wrapper, pero todavía no me gusta esta solución ... 'SharedPreferences' ya tiene el método' getInt', así que aún espero encontrar la manera de decir 'PreferenceActivity' para guardar el valor como int - toda la funcionalidad está ahí ... simplemente no funciona como deseó ... – Laimoncijus

0

Yo tenía el mismo problema. (Quería que SharedPreference me diera un número de puerto que almacené en un archivo xml de preferencias como defaultValue).

Implementar todos los métodos de SharedPreferences sería mucho esfuerzo, por lo que escribir un método personalizado en la clase que instancia las SharedPreferences, como broot sugirió que sería lo mejor, creo.

Usted puede aswell sólo tiene que utilizar el método estático de enteros en la línea donde lo necesite:

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

A pesar de que una respuesta ha sido estacionado aceptado Me gustaría compartir una forma más corta para lograr esto:

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

Dado que ya ha establecido que sólo se pueden introducir números no esto será a través de cualquier excepción. todavía para completar mi respuesta:

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