【问题标题】:ListPreference dependencyListPreference 依赖项
【发布时间】:2011-04-27 13:20:24
【问题描述】:

我有一个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"

谢谢!

【问题讨论】:

    标签: android dependencies preferences


    【解决方案1】:

    你可以做这样的事情的唯一方法是编程。

    您必须在 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:itemList 和 itemList2 变量应该声明为 final。无论如何,我投了赞成票,因为你的回答对我很有帮助!
    • 是否可以让 itemList2 依赖于 hidden 布尔值(不显示在首选项屏幕上的首选项),然后只需设置此隐藏值在上面的代码中是真还是假?效果是一样的,但我认为如果您有很多取决于 itemList 的偏好(而不仅仅是一个),它会稍微方便一些。如果可能的话,你怎么能隐藏这个值?
    • 我有另一个用于隐藏首选项的 XML 文件,我不想在活动中显示(仅供内部使用)。您可以以这种方式声明它并且永远不会将其加载到首选项活动中,而您可以像其他首选项一样访问(读/写)它
    • 刚刚尝试了解决方案。工作,但当用户更改屏幕方向禁用控件再次启用。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我尝试编辑@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" />
      

      【讨论】:

        【解决方案4】:

        在xml中添加一行

        app:isPreferenceVisible="false"
        

        然后在java中的item3中添加一个onClickListener,在选中时将item设置为true

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-18
          • 1970-01-01
          • 2014-08-20
          • 2016-02-18
          • 2016-08-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多