2010-10-19 39 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" /> 

然后,我有另一种偏好,如果“项目3”在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

我会去上肢体并说这是我见过的最可怕的答案。 – 2012-03-07 14:56:14

+2

@Emmanuel:itemList和itemList2变量应声明为final。无论如何,我投了票,因为你的回答对我很好! – 2012-08-13 16:37:40

+1

是否有可能让itemList2依赖* hidden *布尔值(首选项不会显示在首选项屏幕上),然后在上面的代码中将该隐藏值设置为true或false?效果是一样的,但我认为如果你有很多喜好取决于itemList(而不是一个),它会稍微方便一些。如果可能的话,你怎么能隐藏这个值? – Malabarba 2013-04-17 14:51:38

6

子类ListPreference类,并重写setValueshouldDisableDependence方法。

setValue将在super.setValue后调用notifyDependencyChange(shouldDisableDependents())实际更改值。

shouldDisableDependence仅当当前值为item3或存储在mDepedenceValue中的任何其他所需值时才返回false。

@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类,并覆盖setValueshouldDisableDependence方法。

setValue将在super.setValue后调用notifyDependencyChange(shouldDisableDependents())实际更改值。

shouldDisableDependence仅当当前值为item3或存储在mDepedenceValue中的任何其他所需值时才返回false。

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