例如:我的首选项屏幕中有三个复选框,每个复选框上有3个不同的listpreference(A,B,C)
。我想让用户一次只选择一个复选框。我如何实现这一目标?
首选项屏幕中没有单选按钮
我无法使用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页,这里几乎所有关于这些的内容但是我找不到任何答案。
最诚挚的问候,
提前致谢..
答案 0 :(得分:14)
您可以覆盖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
}
}
}
答案 1 :(得分: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>
后记:
如果您不想使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;
}