2010-10-19 4 views
26

У меня есть ListPreference, который выглядит примерно так:ListPreference зависимость

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

Тогда, у меня есть еще одно преимущество, которое должно быть разрешено только в случае «item3» выбран в ListPreference.

Могу ли я как-то выполнить это с помощью android:dependency? Что-то вроде android:dependency="itemList:item3"

Спасибо!

ответ

28

Единственный способ, которым вы можете сделать что-то подобное, программно.

Вам нужно будет настроить прослушиватель изменений в ListPreference, а затем включить/отключить другой.

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

Если бы я был вами, я бы даже не показал второе предпочтение, если первое не установлено должным образом. Для этого вам нужно объявить предпочтение вручную (не в XML) и добавить/удалить его вместо включения/отключения.

Теперь это не самый лучший ответ, который вы когда-либо видели!

Эммануэль

+5

Я пойду на конечности и скажите, что это самый лучший ответ, который я когда-либо видел. –

+2

@Emmanuel: переменные itemList и itemList2 должны быть объявлены окончательными. Во всяком случае, я голосовал, потому что ваш ответ отлично подействовал на меня! –

+1

Было бы возможно, чтобы itemList2 зависел от * hidden * boolean value (предпочтения, которые не отображаются на экране предпочтений), а затем просто установите это скрытое значение в true или false в вашем коде выше? Эффект будет таким же, но я думаю, что было бы немного удобнее, если бы у вас было много предпочтений в зависимости от itemList (а не только одного). Если возможно, как бы вы могли скрыть это значение? – Malabarba

6

Подкласс ListPreference класс и переопределить setValue и shouldDisableDependence методы.

setValue будет звонить notifyDependencyChange(shouldDisableDependents()) после super.setValue, когда значение фактически изменено.

shouldDisableDependence возвращает false только в том случае, если текущее значение равно item3 или любое другое желаемое значение, хранящееся в 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

Я попытался отредактировать решение @waterdragon, но это было «отклонено пэром». Не уверен, почему, поскольку он по-прежнему является его решением, но дает конкретный пример.

Подкласс ListPreference класс и переопределение setValue и shouldDisableDependence методы.

setValue будет звонить notifyDependencyChange(shouldDisableDependents()) после super.setValue, когда значение фактически изменено.

shouldDisableDependence возвращает false только в том случае, если текущее значение равно item3 или любое другое желаемое значение, хранящееся в 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); 
    } 
} 

Обновите attrs.xml:

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

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

и внутри ваших предпочтений XML связать его с любым другим предпочтением, которое зависит от него:

<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" /> 
Смежные вопросы