5

例如:我的首选项屏幕中有三个复选框,listpreference(A,B,C)每个复选框有 3 个不同的复选框。我想让用户一次只选择一个复选框。我如何实现这一目标?

  1. 首选项屏幕中没有单选按钮

  2. 我不能使用 Listpreference ,如果我可以使用它

      ListPreference
        android:key="livewallpaper_testpattern"
        android:title="@string/livewallpaper_settings_title"
        android:summary="@string/livewallpaper_settings_summary"
        android:entries="@array/livewallpaper_testpattern_names"
        android:entryValues="@array/livewallpaper_testpattern_prefix"
    

此 Listprefrence 的数组是“blue”、“red”、“white”

如果是蓝色 ListPreference A 取决于蓝色

如果是红色 ListPreference B 取决于红色

如果是白色 ListPreference C 取决于白色

我怎样才能做到这一点?

我在谷歌搜索了 3-4 页,这里几乎所有关于这些的内容,但我找不到任何答案。

最好的祝福,

提前致谢..

4

2 回答 2

15

您可以onSharedPreferenceChanged在您的PreferenceActivity类中覆盖并以编程方式启用/禁用适当的首选项:

public class MyPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
    ...
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals("livewallpaper_testpattern")) {
            if (/* check if livewallpaper_testpattern equals to blue */) {
                findPreference("ListPreferenceKey_A").setEnabled(true);
                findPreference("ListPreferenceKey_B").setEnabled(false);
                findPreference("ListPreferenceKey_C").setEnabled(false);
            } else if (/* check if livewallpaper_testpattern equals to red */) {
                // enable B, disable A & C
            } else if (/* check id livewallpaper_testpattern equals to white */) {
                // enable C, disable A & B
            }
        }
    }
于 2011-03-30T09:38:04.307 回答
0

另一种方法是创建一个抽象助手类。它使用反射来访问该类registerDependent()私有的方法Preference

public abstract class MultiDependencies {

    private static final String NOLESHNS="http://nolesh.com";

    private Preference host;        
    private HashMap<String, Boolean> dependencies = new HashMap<>();

    //We have to get access to the 'findPreferenceInHierarchy' function
    //from the extended preference, because this function is protected
    protected abstract Preference findPreferenceInHierarchy(String key);

    public MultiDependencies(Preference host, AttributeSet attrs){

        this.host = host;

        final String dependencyString = getAttributeStringValue(attrs, NOLESHNS, "dependencies", null);

        if (dependencyString != null) {
            String[] dependencies = dependencyString.split(",");
            for (String dependency: dependencies) {
                this.dependencies.put(dependency.trim(), false);
            }
        }
    }

    void onAttachedToActivity(){
        if(isEnabled()) registerDependencies();
    }

    void onDependencyChanged(Preference dependency, boolean disableDependent){
        setDependencyState(dependency.getKey(), !disableDependent);
        setHostState();
    }

    private void setDependencyState(String key, boolean enabled){
        for (Map.Entry<String, Boolean> entry: dependencies.entrySet()) {
            if (entry.getKey().equals(key)) entry.setValue(enabled);
        }
    }

    private String getAttributeStringValue(AttributeSet attrs, String namespace, String name, String defaultValue) {
        String value = attrs.getAttributeValue(namespace, name);
        if(value == null) value = defaultValue;
        return value;
    }

    private void registerDependencies() {
        for (final Map.Entry<String, Boolean> entry: dependencies.entrySet()) {
            final Preference preference = findPreferenceInHierarchy(entry.getKey());

            if (preference != null) {

                try {
                    final Class<Preference> prefClass = Preference.class;
                    final Method registerMethod = prefClass.getDeclaredMethod("registerDependent", Preference.class);
                    registerMethod.setAccessible(true);
                    registerMethod.invoke(preference, host);
                } catch (final Exception e) {
                    e.printStackTrace();
                }

                boolean enabled = preference.isEnabled();
                if(preference instanceof CheckBoxPreference){
                     enabled &= ((CheckBoxPreference) preference).isChecked();
                }

                setDependencyState(preference.getKey(), enabled);
            }
        }
        setHostState();
    }

    private void setHostState(){
        boolean enabled = true;
        for (Map.Entry<String, Boolean> entry: dependencies.entrySet()) {
            if (!entry.getValue()){
                enabled = false;
                break;
            }
        }
        host.setEnabled(enabled);
    }

    public boolean isEnabled(){
        return dependencies.size()>0;
    }

}

然后扩展您的checkboxPreference或任何其他类,如下所示:

public class MultiDependencyCheckboxPrereference extends CheckBoxPreference {

    MultiDependencies multiDependencies;

    public MultiDependencyCheckboxPrereference(Context context, AttributeSet attrs) {
        super(context, attrs);

        multiDependencies = new MultiDependencies(this, attrs) {
            @Override
            protected Preference findPreferenceInHierarchy(String key) {
                //Getting access to the protected function
                return MultiDependencyCheckboxPrereference.this.findPreferenceInHierarchy(key);
            }
        };
    }

    @Override
    protected void onAttachedToActivity() {
        super.onAttachedToActivity();
        multiDependencies.onAttachedToActivity();
    }

    @Override
    public void onDependencyChanged(Preference dependency, boolean disableDependent) {
        if(multiDependencies.isEnabled()) 
            multiDependencies.onDependencyChanged(dependency, disableDependent);
        else super.onDependencyChanged(dependency, disableDependent);
    }
}

最后,您可以像这样使用您的新偏好:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:nolesh="http://nolesh.com">

<com.nolesh.android.widgets.MultiDependencyCheckboxPrereference
    android:key="com_nolesh_test"
    android:defaultValue="false"
    android:title="test"
    nolesh:dependencies="com_nolesh_dep1, com_nolesh_dep2"
    />

<CheckBoxPreference
    android:key="com_nolesh_dep1"
    android:defaultValue="false"
    android:title="dependency 1"
    />

<CheckBoxPreference
    android:key="com_nolesh_dep2"
    android:defaultValue="false"
    android:title="dependency 2"
    />

</PreferenceScreen>

Post Scriptum: 如果您不想使MultiDependecies类抽象并覆盖该findPreferenceInHierarchy功能,则可以使用反射:

private Preference findPreferenceInHierarchy(String key){
    try {
        final Class<Preference> prefClass = Preference.class;
        final Method registerMethod = prefClass.getDeclaredMethod(
                    "findPreferenceInHierarchy", String.class);
        registerMethod.setAccessible(true);
        return (Preference) registerMethod.invoke(host, key);
    } catch (final Exception e) {
        e.printStackTrace();
    }
    return null;
}
于 2019-08-17T05:51:11.100 回答