Android: Trabajando con Preferencias

viernes, 17 de mayo de 2013 Etiquetas: ,

Introducción

La pantalla de preferencias en una aplicación es algo habitual, bien sea para guadar datos de conexión a una página web, para guardar opciones de visualización o cualquier configuración que creas conveniente que el usuario pueda personalizar. Android nos proporciona un mecanismo muy sencillo para crear una pantalla para gestionarlas.

En esta entrada vamos a ver como podemos realizar algunas operciones por código sobre este formulario, por ejemplo, como habilitar o deshabilitar una serie de opciones dependiendo del valor de una opción.

Solución

Primero vamos a crer nuestra pantalla de preferencias. Creamos el archivo preferencias.xml en el directorio res/xml. Donde definimos tres opciones tipo check, como vemos en el siguiente código.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="preferencias" >

    <PreferenceCategory android:title="@string/pref_section" >
        <CheckBoxPreference
            android:defaultValue="false"
            android:key="pref_1"
            android:summary="@string/summmary_pref_1"
            android:title="@string/title_pref_1" />

    <CheckBoxPreference
            android:defaultValue="false"
            android:key="pref_2"
            android:summary="@string/summmary_pref_2"
            android:title="@string/title_pref_2" />
    
    <CheckBoxPreference
            android:defaultValue="false"
            android:key="pref_3"
            android:summary="@string/summmary_pref_3"
            android:title="@string/title_pref_3" />
    </PreferenceCategory>

</PreferenceScreen>

Ahora creamos la Activity que se encargará de crear la pantalla de configuración. Es muy simple, solo tenemos que heredar de la clase PreferenceActivy e indicarle el archivo de configuración que queremos que utilice. Vamos a verlo:

public class Preferencias extends PreferenceActivity{
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    addPreferencesFromResource(R.xml.preferencias);
  }
}

Bien ya tenemos nuestra pantalla de configuración con el aspecto típico de las aplicaciones Android, ha sido fácil. Ahora bien, ahora queremos que las opciones dos y tres solo estén disponibles si la primera esta activada, ¿cómo lo podemos hacer?. Es sencillo vamos a expandier nuestra clase:

public class Preferencias extends PreferenceActivity{
  public static final String KEY_1 = "pref_1";
  public static final String KEY_2 = "pref_2";
  public static final String KEY_3 = "pref_3";
 
  private SharedPreferences prefs;
 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 
    prefs = PreferenceManager
       .getDefaultSharedPreferences(getApplicationContext());
 
    addPreferencesFromResource(R.xml.preferencias); 
    
    boolean isActive = prefs.getBoolean(KEY_1, false); 
    findPreference(KEY_2).setEnabled(isActive);
  findPreference(KEY_3).setEnabled(isActive);
  }
  
}
Podemos ver como al crear la Activity leemos el valor de la primera preferencia, y dependiendo el valor de esta habilitamos o no las otras dos opciones. También bastante sencillo.

También podemos realizar una serie de comprobaciones sobre el valor de las opciones cuando la introduce el usuario. Podemos querer que no se puedan marcar las tres opciones a la vez (una restricción tonta de prueba).

public class Preferencias extends PreferenceActivity
       implements OnSharedPreferenceChangeListener{
  public static final String KEY_1 = "pref_1";
  public static final String KEY_2 = "pref_2";
  public static final String KEY_3 = "pref_3";
 
  private SharedPreferences prefs;
 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 
    prefs = PreferenceManager
       .getDefaultSharedPreferences(getApplicationContext());
 
    addPreferencesFromResource(R.xml.preferencias); 
    
    boolean isActive = prefs.getBoolean(KEY_1, false); 
    findPreference(KEY_2).setEnabled(isActive);
  findPreference(KEY_3).setEnabled(isActive);
  }
  
  @Override
  protected void onResume() {
    super.onResume();
    prefs.registerOnSharedPreferenceChangeListener(this);
  }

  @Override
  protected void onPause() {
    super.onPause();
    prefs.unregisterOnSharedPreferenceChangeListener(this);
  }
  
  @Override
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    if (key.equals(KEY_1) || key.equals(KEY_2) || key.equals(KEY_3) ) {
      if (prefs.getBoolean(KEY_1, false) && 
          prefs.getBoolean(KEY_2, false) && 
          prefs.getBoolean(KEY_3, false) ){ 
        
        SharedPreferences.Editor prefEditor = prefs.edit();
        prefEditor.putBoolean(key, false);
        prefEditor.commit();

 Toast.makeText(this, "Mensaje de Error",Toast.LENGTH_LONG).show();
 reload();
       }    
     }  
  }
  
  private void reload() {
    startActivity(getIntent());
    finish(); 
  }
}
En esta ocasión implementamos la interfaz para OnSharedPreferenceChangeListener para que nos avise del cambio que se produce en las preferencias. En el OnResume nos registramos nuestra clase para que nos avise de los cambios y en el onPause quitamos lel registro.

En la función onSharedPreferenceChanged comprobamos si la opción modificada es una de la que nos interesa, si es así comprobamos si los demás valores son todos true, si es así modificamos por código el valor que se ha activado para desactivarlo y avisamos al usuario. Recargamos la actividad para que se muestre el valor que hemos cambiado.

El ejemplo es sencillo, pero se podría usar para validar datos que cumplen un patrón, como podría ser direcciones de correo electronico, letra de un NIF por ejemplo.

Como hemos visto en esta entrada la creación de una pantalla de preferencias es muy rápida y fácil, pero nos sigue proporcionando una serie de herramientas para una gestión avanzada de la misma, que nos permite realizar comprobaciones de integridad de datos o dependencia entre ellos.

0 comentarios:

Publicar un comentario