虽然正在记录,但是通过使用"%s"
,我可以将所选值显示为摘要,但它无法按预期工作。
http://developer.android.com/reference/android/preference/ListPreference.html#getSummary%28%29
我有以下preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/preference_xxx_category">
<CheckBoxPreference
android:title="@string/preference_xxx_mode_title"
android:defaultValue="false"
android:summary="@string/preference_xxx_mode_summary"
android:key="xxxModePreference" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/preference_yyy_category">
<ListPreference
android:title="@string/preference_yyy_mode_title"
android:defaultValue="0"
android:entries="@array/yyy"
android:entryValues="@array/yyy_values"
android:summary="%s"
android:key="yyyModePreference" />
</PreferenceCategory>
</PreferenceScreen>
这是我的arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="yyy">
<item>Display value 0</item>
<item>Display value 1</item>
</string-array>
<string-array name="yyy_values">
<item>0</item>
<item>1</item>
</string-array>
</resources>
我期望通过使用以下Java代码构建完整的首选项活动,使用复选框和列表首选项,每当我执行选择时,列表首选项的摘要文本都可以自动更新。摘要文本将在显示值0 和显示值1 之间切换。
public class Preferences extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
但是,我意识到列表首选项的摘要文本不会自动更新。只有当我在复选框上执行勾选/取消勾选时,只有整个活动无效,列表首选项的摘要文本才会更新。
因此,我必须修改我的代码,看起来更加繁琐。
public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onResume() {
super.onResume();
// Cumbersome way to make sure list preference's summary text is being updated.
final String key = "yyyModePreference";
ListPreference listPreference = (ListPreference)findPreference(key);
final String value = PreferenceManager.getDefaultSharedPreferences(this).getString(key, key);
final int index = listPreference.findIndexOfValue(value);
if (index >= 0) {
final String summary = (String)listPreference.getEntries()[index];
listPreference.setSummary(summary);
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences options, String key) {
// Cumbersome way to make sure list preference's summary text is being updated.
if (key.equals("yyyModePreference")) {
ListPreference listPreference = (ListPreference)findPreference(key);
final String value = options.getString(key, key);
final int index = listPreference.findIndexOfValue(value);
if (index >= 0) {
final String summary = (String)listPreference.getEntries()[index];
listPreference.setSummary(summary);
}
}
}
}
这是正确的方法吗?有没有简化的方法,以确保只要选择发生变化,ListPreference的摘要文本就会自动更新。
答案 0 :(得分:25)
这是KITKAT之前的平台上存在的错误(即android-4.4_r0.7),它由commit 94c02a1修复
@ilomambo的解决方案有效,但可能不是最好的解决方案。我仔细阅读了ListPreference
的来源并提出了这个解决方案:
文件:ListPreferenceCompat.java
package com.example.yourapplication;
import android.content.Context;
import android.os.Build;
import android.preference.ListPreference;
import android.text.TextUtils;
import android.util.AttributeSet;
public class ListPreferenceCompat extends ListPreference {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ListPreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ListPreferenceCompat(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListPreferenceCompat(Context context) {
super(context);
}
// NOTE:
// The framework forgot to call notifyChanged() in setValue() on previous versions of android.
// This bug has been fixed in android-4.4_r0.7.
// Commit: platform/frameworks/base/+/94c02a1a1a6d7e6900e5a459e9cc699b9510e5a2
// Time: Tue Jul 23 14:43:37 2013 -0700
//
// However on previous versions, we have to work around it by ourselves.
@Override
public void setValue(String value) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
super.setValue(value);
} else {
String oldValue = getValue();
super.setValue(value);
if (!TextUtils.equals(value, oldValue)) {
notifyChanged();
}
}
}
}
如果您需要在xml中使用ListPreference
,只需将代码替换为com.example.yourapplication.ListPreferenceCompat
。
这在我运行Android 4.3的三星S4设备上以及我的一个生产应用程序中整齐地运行。
答案 1 :(得分:6)
我猜它是一种奇怪的错误,因为我在运行Android 2.3.3 的模拟器上测试了它并且它不起作用,但是当我在 4.0上测试它时.3 它起作用了。我在 ListPreference 的xml中做了android:summary="%s"
,这就是全部。
答案 2 :(得分:1)
恕我直言,这是一个错误。 ListPreference.java#builder.setSingleChoiceItems()中定义的onClickListener()不会调用notifyChanged()
我碰巧基于该代码编写了自己的ListPreference,并遇到了与OP相同的问题,我添加了notifyChanged()
:
...
dialog.dismiss();
notifyChanged(); // <<<<<<<<<<
}
});
现在,我选择它时会立即更新首选项摘要。 它不依赖于Android版本,因此ListPreference就像这样编码。