2010-10-19 16 views
26

Ho un ListPreference che simile a questa:ListPreference dipendenza

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

Poi, ho un altro preferenza che dovrebbe essere attivata solo se si seleziona "item3" nel ListPreference.

Posso farlo in qualche modo con android:dependency? Qualcosa come android:dependency="itemList:item3"

Grazie!

risposta

28

L'unico modo per fare qualcosa di simile è programmaticamente.

Dovresti impostare un listener di modifiche su ListPreference e abilitare/disabilitare l'altro.

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; 
    } 
}); 

Se fossi in te, non visualizzerei nemmeno la seconda preferenza se la prima non è impostata correttamente. Per farlo devi dichiarare la preferenza manualmente (non nel XML) e aggiungerla/rimuoverla invece di abilitare/disabilitare.

Ora non è questa la risposta migliore che abbiate mai visto ?!

Emmanuel

+5

andrò su un arto e dire che questa è la migliore risposta che abbia mai visto. –

+2

@Emmanuel: le variabili itemList e itemList2 devono essere dichiarate definitive. Comunque, ho votato, perché la tua risposta ha funzionato alla grande per me! –

+1

Sarebbe possibile avere itemList2 depende su un valore booleano * nascosto * (una preferenza che non appare nella schermata delle preferenze), e quindi basta impostare questo valore nascosto su vero o falso nel codice sopra? L'effetto sarebbe lo stesso, ma penso che sarebbe leggermente più conveniente se avessi molte preferenze a seconda di ItemList (invece di una sola). Se possibile, come potresti nascondere questo valore? – Malabarba

6

sottoclasse ListPreference classe e ignorare setValue e shouldDisableDependence metodi.

setValue chiamerà notifyDependencyChange(shouldDisableDependents()) dopo il super.setValue quando il valore viene effettivamente modificato.

shouldDisableDependence restituisce false solo se il valore corrente è item3 o qualsiasi altro valore desiderato memorizzato in 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

Ho provato a modificare la soluzione @waterdragon ma era "peer respinto". Non so perché, perché è ancora la sua soluzione, ma fornisce un esempio concreto.

Sottoclasse ListPreference classe e override setValue e shouldDisableDependence metodi.

setValue chiamerà notifyDependencyChange(shouldDisableDependents()) dopo il super.setValue quando il valore viene effettivamente modificato.

shouldDisableDependence restituisce false solo se il valore corrente è item3 o qualsiasi altro valore desiderato memorizzato in 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); 
    } 
} 

Aggiornare l'attrs.xml:

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

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

e dentro la vostra preferenza XML legarlo a qualsiasi altra preferenza che dipende da questo:

<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" /> 
Problemi correlati