[英]ListPreference: use string-array as Entry and integer-array as Entry Values doesn't work
I'm using in a settings.xml file a ListPreference. 我在settings.xml文件中使用ListPreference。 I want to show the user a list of 3 options to select. 我想向用户显示3个选项列表。 When the user chooses one of the options in the Settings, I get this error: 当用户在“设置”中选择一个选项时,出现此错误:
java.lang.NullPointerException
at android.preference.ListPreference.onDialogClosed(ListPreference.java:264)
at android.preference.DialogPreference.onDismiss(DialogPreference.java:381)
at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1228)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
This is the code of the ListPreference: 这是ListPreference的代码:
<ListPreference
android:entries="@array/date_alignement"
android:entryValues="@array/date_alignement_values"
android:key="settings_date_alignement"
android:summary="@string/settings_date_alignement_summary"
android:title="@string/settings_date_alignement_title" />
And here are the arrays I use to populate the entries: 这是我用来填充条目的数组:
<string-array name="date_alignement">
<item>"Top"</item>
<item>"Center"</item>
<item>"Bottom"</item>
</string-array>
<integer-array name="date_alignement_values">
<item >0</item>
<item >1</item>
<item >2</item>
</integer-array>
In my onSharedPreferenceChanged I use those values in this way: 在我的onSharedPreferenceChanged中,我通过以下方式使用这些值:
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
//Text
mAlignment = mPrefs.getInt(PREF_ALIGNMENT, 1);
switch (mAlignment) {
case 0:
offsetY = mHeight/3.0f;
break;
case 2:
offsetY = mHeight*2.0f/3.0f;
break;
default:
offsetY = mHeight/2.0f;
break;
}
}
If I use another string-array for the entryValues it works. 如果我对entryValues使用另一个字符串数组,它将起作用。 For example if I use the same string array as values and entries: 例如,如果我使用相同的字符串数组作为值和条目:
android:entries="@array/date_alignement"
android:entryValues="@array/date_alignement"
then I have to change my code a little but it works: 然后我必须稍微修改一下代码,但它可以工作:
if(mAlignment.equalsIgnoreCase("center")) {
offsetY = mHeight/2.0f;
} else if(mAlignment.equalsIgnoreCase("top")) {
offsetY = mHeight/3.0f;
} else if(mAlignment.equalsIgnoreCase("bottom")) {
offsetY = mHeight*2.0f/3.0f;
}
Why I can't use a string-array and an integer-array for a ListPreference entries and values? 为什么我不能对ListPreference条目和值使用字符串数组和整数数组?
The answer is simple: because the Android is designed this way. 答案很简单:因为Android是按这种方式设计的。 It just uses String
arrays for both entries and entry values and that's all. 它仅将String
数组用于条目和条目值,仅此而已。 And I can't see any problem in this fact, since you can easily convert a String
to an int
using the Integer.parseInt()
method. 而且我看不到任何问题,因为您可以使用Integer.parseInt()
方法轻松地将String
转换为int
。 Hope this helps. 希望这可以帮助。
The answer is listed in List Preference Documentation . 答案在“ 列表首选项文档”中列出 。
int findIndexOfValue (String value)
will return the index for given value and the argument is taken as a String, so the entryValues array should be a string array to get this work. 将返回给定值的索引,并且参数作为字符串使用,因此entryValues数组应为字符串数组才能完成此工作。
You can convert your entry values to strings to keep ListPreference
happy and then convert them to int
s when talking to the persistent data store. 您可以将输入值转换为字符串,以使ListPreference
满意,然后在与持久数据存储区通信时将其转换为int
。
"1", "2", "3"
etc 设置条目值时,请使用字符串而不是整数: "1", "2", "3"
等 IntListPreference
that persists the values as ints 创建一个自定义的IntListPreference
,将值持久保存为int preferences.xml
file, change the <ListPreference>
into a <your.app.package.IntListPreference>
在您的preferences.xml
文件中,将<ListPreference>
更改为<your.app.package.IntListPreference>
Here's a sample implementation. 这是一个示例实现。 Tested and working on AndroidX Preference 1.0.0. 经过测试并在AndroidX Preference 1.0.0上工作。
public class IntListPreference extends ListPreference {
public IntListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public IntListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public IntListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public IntListPreference(Context context) {
super(context);
}
@Override
protected boolean persistString(String value) {
int intValue = Integer.parseInt(value);
return persistInt(intValue);
}
@Override
protected String getPersistedString(String defaultReturnValue) {
int intValue;
if (defaultReturnValue != null) {
int intDefaultReturnValue = Integer.parseInt(defaultReturnValue);
intValue = getPersistedInt(intDefaultReturnValue);
} else {
// We haven't been given a default return value, but we need to specify one when retrieving the value
if (getPersistedInt(0) == getPersistedInt(1)) {
// The default value is being ignored, so we're good to go
intValue = getPersistedInt(0);
} else {
throw new IllegalArgumentException("Cannot get an int without a default return value");
}
}
return Integer.toString(intValue);
}
}
The following worked for me: 以下为我工作:
String objectName = prefs.getString("listPrefMelodyYd1", "");
switch (objectName.toUpperCase()) {
case "1":
playSound(catSound);
break;
case "2":
playSound(dogSound);
break;
case "3":
playSound(cowSound);
break;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.