2010-10-19 11 views
26

Tengo una ListPreference, que algo como esto:ListPreference dependencia

<ListPreference 
android:title="Choose item" 
android:summary="..." 
android:key="itemList" 
android:defaultValue="item1" 
android:entries="@array/items" 
android:entryValues="@array/itemValues" /> 

entonces, tengo otra preferencia que sólo debe ser habilitada si se selecciona "elemento3" en el ListPreference.

¿Puedo de alguna manera lograr esto con android:dependency? Algo así como android:dependency="itemList:item3"

¡Gracias!

Respuesta

28

La única forma de que pueda hacer algo como esto es programáticamente.

Tendría que configurar un detector de cambios en ListPreference y luego habilitar/deshabilitar el otro.

itemList = (ListPreference)findPreference("itemList"); 
itemList2 = (ListPreference)findPreference("itemList2"); 
itemList.setOnPreferenceChangeListener(new 
Preference.OnPreferenceChangeListener() { 
    public boolean onPreferenceChange(Preference preference, Object newValue) { 
    final String val = newValue.toString(); 
    int index = itemList.findIndexOfValue(val); 
    if(index==3) 
     itemList2.setEnabled(true); 
    else 
     itemList2.setEnabled(false); 
    return true; 
    } 
}); 

Si yo fuera usted, ni siquiera mostraría la segunda preferencia si la primera no está configurada correctamente. Para hacerlo, debe declarar la preferencia manualmente (no en el XML) y agregarla/eliminarla en lugar de habilitarla/deshabilitarla.

¿Ahora esta no es la mejor respuesta que hayas visto?

Emmanuel

+5

Voy a salir en una extremidad y decir que esta es la mejor respuesta que he visto en mi vida. –

+2

@Emmanuel: las variables itemList e itemList2 deben declararse finales. De todos modos, voté, porque tu respuesta funcionó muy bien para mí. –

+1

¿Sería posible que itemList2 dependa de un valor booleano * oculto * (una preferencia que no aparece en la pantalla de preferencias) y luego simplemente establezca este valor oculto en verdadero o falso en su código anterior? El efecto sería el mismo, pero creo que sería un poco más conveniente si tuviera muchas preferencias según itemList (en lugar de solo una). Si es posible, ¿cómo podría ocultar este valor? – Malabarba

6

Subclase ListPreference clase, y anular setValue y shouldDisableDependence métodos.

setValue llamará notifyDependencyChange(shouldDisableDependents()) después de super.setValue cuando el valor realmente se cambie.

shouldDisableDependence devuelve falso solo si el valor actual es item3, o cualquier otro valor deseado almacenado en mDepedenceValue.

@Override 
public void setValue(String value) { 
    String mOldValue = getValue(); 
    super.setValue(value); 
    if (!value.equals(mOldValue)) { 
     notifyDependencyChange(shouldDisableDependents()); 
    } 
} 

@Override 
public boolean shouldDisableDependents() { 
    boolean shouldDisableDependents = super.shouldDisableDependents(); 
    String value = getValue(); 
    return shouldDisableDependents || value == null || !value.equals(mDepedenceValue); 
} 
2

Traté de editar la solución de @waterdragon pero fue "rechazada por pares". No estoy seguro de por qué porque sigue siendo su solución, pero proporciona un ejemplo concreto.

Subclase ListPreference clase, y reemplaza setValue y shouldDisableDependence métodos.

setValue llamará notifyDependencyChange(shouldDisableDependents()) después de super.setValue cuando el valor realmente se cambie.

shouldDisableDependence devuelve falso solo si el valor actual es item3, o cualquier otro valor deseado almacenado en mDepedenceValue.

package xxx; 

import android.content.Context; 
import android.content.res.TypedArray; 
import android.preference.ListPreference; 
import android.util.AttributeSet; 

import xxx.R; 

public class DependentListPreference extends ListPreference { 

    private final String CLASS_NAME = this.getClass().getSimpleName(); 
    private String dependentValue = ""; 

    public DependentListPreference(Context context) { 
     this(context, null); 
    } 
    public DependentListPreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     if (attrs != null) { 
      TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DependentListPreference); 
      dependentValue = a.getString(R.styleable.DependentListPreference_dependentValue); 
      a.recycle(); 
     } 
    } 

    @Override 
    public void setValue(String value) { 
     String mOldValue = getValue(); 
     super.setValue(value); 
     if (!value.equals(mOldValue)) { 
      notifyDependencyChange(shouldDisableDependents()); 
     } 
    } 

    @Override 
    public boolean shouldDisableDependents() { 
     boolean shouldDisableDependents = super.shouldDisableDependents(); 
     String value = getValue(); 
     return shouldDisableDependents || value == null || !value.equals(dependentValue); 
    } 
} 

actualización de su attrs.xml:

<attr name="dependentValue" format="string" /> 

<declare-styleable name="DependentListPreference"> 
    <attr name="dependentValue" /> 
</declare-styleable> 

y en el interior de su preferencia xml atar a cualquier otra preferencia que depende de él:

<xxx.DependentListPreference 
     android:key="pref_key_wifi_security_type" 
     android:title="Wi-Fi Security Type" 
     app:dependentValue="1" 
     android:entries="@array/wifi_security_items" 
     android:entryValues="@array/wifi_security_values" /> 

    <EditTextPreference 
     android:key="pref_key_wifi_security_key" 
     android:title="WPA2 Security Key" 
     android:summary="Tap to set a security key" 
     android:password="true" 
     android:dependency="pref_key_wifi_security_type" /> 
Cuestiones relacionadas