Android 列表首选项: 有摘要作为选择值?

我有一个 Preferences 活动,它使用 XML 文件定义的 List Preferences。如何将列表活动的摘要设置为所选择的值?

44668 次浏览

首先在 onCreate 中获得对 ListPreferences 的引用。您可以使用 findPreferences ()。例如:

ListPreference pref = (ListPreference) findPreference("thePreferencesKey");

然后,当您第一次加载 Activity 时,当首选项值发生变化时,使用您想要获取 ListPreferences 值的任何方法,并使用以下方法设置摘要:

pref.setSummary(theNewString);

可以使用 OnPreferenceChangeListener动态更改摘要。问题在于它获取的是选定的值(来自 android:entryValues) ,而不是标题(android:entries)。在下面的代码中,我使用了 toString(),但是正确的解决方案是找到值的标题。不管怎样,这个想法奏效了:

public class Preferences extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.your_prefs);


ListPreference listPreference = (ListPreference) findPreference("preference_key");
if(listPreference.getValue()==null) {
// to ensure we don't get a null value
// set first value by default
listPreference.setValueIndex(0);
}
listPreference.setSummary(listPreference.getValue().toString());
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
preference.setSummary(newValue.toString());
return true;
}
});
}
}

我也想实现一些类似的东西,但与 https://stackoverflow.com/a/8155029/592025的问题是,它显示了我的偏好值(如1,23等)。我想显示与所选值对应的条目(人类可读字符串)。

所以我把它改成了我需要的样子。

listPreference.setSummary(servicePreference.getEntry().toString());
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {


@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Set the value as the new value
listPreference.setValue(newValue.toString());
// Get the entry which corresponds to the current value and set as summary
preference.setSummary(listPreference.getEntry());
return false;
}
});

The trick is to use getEntry() instead of getValue() and once the value is changed, to set the value explicitly and read back the entry.

这是我正在使用的代码,它没有手动调用 setValue,因为我相信这已经在后面的阶段完成了。

Here is an example:

@Override
public boolean onPreferenceChange(Preference preference, Object value)
{
String textValue = value.toString();


ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(textValue);


CharSequence[] entries = listPreference.getEntries();


preference.setSummary(
index >= 0
? entries[index]
: null);


return true;
}

我就是这么做的,效果很好。在 OnSharedPreferenceChangeListener中,我只检查正在更改的内容的键,然后对于 ListPreferences,使用 if 语句将其转换回 Human readable (entry 而不是 entryValue)。很简单。

public class MyPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener{


public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
context = getActivity();


if (context == null){
Log.e("error","context is null");
}


prefs = PreferenceManager.getDefaultSharedPreferences(context);
myFrequencyList = (Preference)  findPreference("frequency_key");
prefs.registerOnSharedPreferenceChangeListener(this);


}




@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {


if(key.equals("frequency_key")){
String freq = sharedPreferences.getString("frequency_key", "8k Hz");
if(freq.equals("8000")){
freq = "8k Hz";
}
else if(freq.equals("16000")){
freq = "16k Hz";
}
else if(freq.equals("22050")){
freq = "22.05k Hz";
}
else if(freq.equals("44100")){
freq = "44.1k Hz";
}
else if(freq.equals("48000")){
freq = "48k Hz";
}
else{
freq = "8k Hz";
}
myFrequencyList.setSummary(freq);
}

Xml 布局

 <ListPreference android:id="@+id/frequency_list"
android:key="frequency_key"
android:summary="8000"
android:title="Sample Rate"
android:defaultValue="8000"
android:dialogTitle="Larger sample rates create better sound quality but larger file sizes."
android:entries="@array/freq_titles"
android:entryValues="@array/freq_values"
/>

Xml 数组

<?xml version="1.0" encoding="utf-8"?>

<string-array name="freq_titles">
<item>48k Hz</item>
<item>44.1k Hz</item>
<item>22.05k Hz</item>
<item>16k Hz</item>
<item>8k Hz</item>
</string-array>


<string-array name="freq_values">
<item>48000</item>
<item>44100</item>
<item>22050</item>
<item>16000</item>
<item>8000</item>
</string-array>

最简单的方法就是让 Android 为你做这件事。假设您希望摘要与选择的值匹配,那么您可以简单地使用 XML 或 Java 中的 setSummary方法 将 ABC0的汇总设置为 "%s"。例如:

<ListPreference
android:key="pref_list"
android:title="A list of preferences"
android:summary="%s"
android:entries="@array/pref_list_entries"
android:entryValues="@array/pref_list_entries_values"
android:defaultValue="0" />

Android 将用首选项的当前字符串值替换 %s,正如 ListPreference的选择器所显示的那样。当您输入活动时,列表的摘要也将被正确设置ーー您不需要编写任何特殊代码来初始化它。

这是带有安卓系统的 也可以

在我发现这个之前,我花了太多的时间与 SharedPreferences听众混在一起。

下面是 midhunhk 的一个扩展版本,它也解决了有用的“ android: Summary”字符串

        // Retrieve & populate flash modes
List<String> flashmodes = params.getSupportedFlashModes();
if (flashmodes != null) {
final ListPreference lp = (ListPreference) findPreference("flash_list");
final String lp_basesummary = "Set the Flash mode. The default is 'auto'";


lp.setEntries(flashmodes.toArray(new CharSequence[flashmodes.size()]));
lp.setEntryValues(flashmodes.toArray(new CharSequence[flashmodes.size()]));
// If there's only one option, make it the default
if (flashmodes.size() == 1)
lp.setValueIndex(0);


lp.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");


lp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {


@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Set the value as the new value
lp.setValue(newValue.toString());
// Get the entry which corresponds to the current value
// and set as summary
preference.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");
return false;
}
});
} else {
// Remove the preference
((PreferenceGroup) findPreference("camera_preference")).removePreference(findPreference("flash_list"));
}


// Retrieve & populate focus modes
List<String> focusmodes = params.getSupportedFocusModes();
if (focusmodes != null) {
final ListPreference lp = (ListPreference) findPreference("focus_mode_list");
final String lp_basesummary = "Set the Focus mode. The default is 'auto'";
...

而且,为了清楚起见,android: Summary 将从相关的 xml 中删除。

这里有一种方法可以在用户选择之后处理铃声首选项的摘要更新。

    final SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());


final RingtonePreference rp_shuttle = (RingtonePreference) findPreference("shuttle_tone");
rp_shuttle.setSummary(RingtoneManager
.getRingtone(getApplicationContext(), Uri.parse(preference.getString("shuttle_tone", "DEFAULT_SOUND")))
.getTitle(this));


rp_shuttle.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {


public boolean onPreferenceChange(Preference mypreference, Object newValue) {
rp_shuttle.setSummary(RingtoneManager.getRingtone(getApplicationContext(), Uri.parse(newValue + ""))
.getTitle(getApplicationContext()));


return true;
}
})

在 PreferenceActivity 上有一个 bindPreferenceSummaryToValue 方法,

你可以像下面这样轻松地将摘要添加到列表中:

private static void bindPreferenceSummaryToValue(Preference preference) {
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);


sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}

在 youtOnCreate 方法中,您可以这样调用 bind 函数:

bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_OF_THE_LIST)));

你可以很容易地用同样的方法添加其他摘要:

bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_1)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_2)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_3)));

在 onCreatePreferences 下可以这样做:

SharedPreferences sharedPreferences =getPreferenceScreen().getSharedPreferences();
PreferenceScreen prefScreen = getPreferenceScreen();
int count = prefScreen.getPreferenceCount();


for (int i = 0; i < count; i++) {
Preference p = prefScreen.getPreference(i);
if (p instanceof ListPreference) {
String value = sharedPreferences.getString(p.getKey(), "");
ListPreference listPreference = (ListPreference) preference;
int prefIndex = listPreference.findIndexOfValue(stringValue);
if (prefIndex >= 0) {
preference.setSummary(listPreference.getEntries()[prefIndex]);
}
}
}

我认为你要找的东西非常简单,你可以想想,在你的 Preference项目中添加以下代码行:

android:summary="%1$s"

所以它看起来像这样:

<ListPreference
android:key="@string/pref_temp_key"
android:title="@string/pref_temp_title"
android:dialogTitle="@string/pref_temp_dialog_title"
android:entries="@array/pref_tempUnit_entries"
android:entryValues="@array/pref_tempUnit_entries"
android:summary="%1$s"
android:defaultValue="@string/pref_temp_default_value" />

如此简单-只需将以下属性添加到 XML 定义-

<ListPreference
...
app:useSimpleSummaryProvider="true"
...
/>