ListPreference 依赖关系

28

我有一个类似于这样的ListPreference

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

我有另一个偏好设置,只有在ListPreference中选择了"item3"时才应启用它。

我是否可以通过android:dependency来实现这一点?类似于android:dependency="itemList:item3"

谢谢!

4个回答

30

你唯一能做到这样的事情就是通过编程实现。

你需要在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中声明),并添加/删除它,而不是启用/禁用它。

现在,这不是您见过的最好的答案吗?!

Emmanuel


5
我会冒险说这是我见过的最棒的答案。 - Juozas Kontvainis
3
@Emmanuel:itemList和itemList2变量应该声明为final。无论如何,我投了一票,因为你的答案对我非常有用! - Giorgio Barchiesi
1
是否有可能让itemList2依赖于一个隐藏的布尔值(即不显示在首选项屏幕上的偏好设置),然后在您的代码中将此隐藏值设置为true或false?效果是相同的,但我认为如果有很多首选项依赖于itemList(而不仅仅是一个),那么这样会稍微更方便一些。如果可能的话,如何隐藏这个值? - Malabarba
我有另一个XML文件,用于隐藏偏好设置,我不想在活动中显示它(仅供内部使用)。您可以这样声明它,并且永远不会在首选项活动中加载它,同时您可以像其他偏好设置一样访问(读/写)它。 - nsL
刚试过了这个解决方案。可以工作,但是当用户更改屏幕方向时,禁用的控件又变成启用状态了。 - Cheburek

7

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

6

我尝试编辑@waterdragon的解决方案,但被“peer rejected”了。不确定为什么,因为它仍然是他的解决方案,但提供了一个具体的例子。

子类化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" />

0
在 XML 中添加该行。
app:isPreferenceVisible="false"

在Java中,为item3添加一个onClickListner,当被选中时将该项设置为true。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接