我在共享首选项中创建列表,当调用onPreferenceChanged()方法时,我想在列表中提取项目的索引,或者在某些情况下提取整数值。我正在尝试按如下方式构建xml数据:
数组中的:
<string-array name="BackgroundChoices">
<item>Dark Background</item>
<item>Light Background</item>
</string-array>
<array name="BackgroundValues">
<item>1</item>
<item>0</item>
</array>
<string-array name="SpeedChoices">
<item>Slow</item>
<item>Medium</item>
<item>Fast</item>
</string-array>
<array name="SpeedValues">
<item>1</item>
<item>4</item>
<item>16</item>
</array>
在首选项xml文件中:
<PreferenceScreen android:key="Settings"
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Settings">
<ListPreference
android:key="keyBackground"
android:entries="@array/BackgroundChoices"
android:summary="Select a light or dark background."
android:title="Light or Dark Background"
android:positiveButtonText="Okay"
android:entryValues="@array/BackgroundValues"/>
<ListPreference
android:key="keySpeed"
android:entries="@array/SpeedChoices"
android:summary="Select animation speed."
android:title="Speed" android:entryValues="@array/SpeedValues"/>
</PreferenceScreen>
所以我的xml不起作用。我知道如何使用字符串数组而不是数组来表示值。我可以提取值字符串并从中得到我想要的但我宁愿(如果可能的话)能够得到值为int,booleans或enums的列表。这样做的习惯方法是什么?
提前感谢,
杰伊答案 0 :(得分:40)
将偏好设置为String
并使用Integer.parseInt()
。我认为实际上有关于你所指的限制的错误报告,但我找不到链接。根据经验,我可以告诉你只需使用Strings
并拯救自己很多挫败感。
请注意其他SO用户,如果您证明我错了,我欢迎它。
答案 1 :(得分:10)
安德鲁是对的,线程是here:
它仍然被评论,但没有变化(无论如何2.3.3)。
.valueOf()的Integer.parseInt()必须工作。如果valueOf()正常运行,请使用它,因为它不像parseInt()那样分配,当你需要像我一样避免使用GC时很有帮助。
答案 2 :(得分:5)
基于Android ListPreference,我创建了IntListPreference。用法很简单 - 只需将此代码段放在首选项xml:
中<org.bogus.android.IntListPreference
android:key="limitCacheLogs"
android:defaultValue="20"
android:entries="@array/pref_download_logs_count_titles"
android:entryValues="@array/pref_download_logs_count_values"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/pref_download_logs_count"
/>
和strings.xml中的内容
<string name="pref_download_logs_count">Number of logs per cache</string>
<string-array name="pref_download_logs_count_titles">
<item>10</item>
<item>20</item>
<item>50</item>
<item>Give me all!</item>
</string-array>
<integer-array name="pref_download_logs_count_values">
<item>10</item>
<item>20</item>
<item>50</item>
<item>-1</item>
</integer-array>
答案 3 :(得分:0)
这是我使用的ListIntegerPreference
类(为com.android.support:preference-v7:24.0.0
编写)。它会覆盖一些方法,并在可能的情况下在Integer
和String
之间进行转换,以便基座ListPreference
无法识别您正在使用Integers
而不是{{1} }}
Strings
我正在使用此功能通过代码创建public class ListIntegerPreference extends ListPreference
{
public ListIntegerPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
}
public ListIntegerPreference(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
public ListIntegerPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ListIntegerPreference(Context context)
{
super(context);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue)
{
int defValue = defaultValue != null ? Integer.parseInt((String)defaultValue) : 0;
int value = getValue() == null ? 0 : Integer.parseInt(getValue());
this.setValue(String.valueOf(restoreValue ? this.getPersistedInt(value) : defValue));
}
@Override
public void setValue(String value)
{
try
{
Field mValueField = ListPreference.class.getDeclaredField("mValue");
mValueField.setAccessible(true);
Field mValueSetField = ListPreference.class.getDeclaredField("mValueSet");
mValueSetField.setAccessible(true);
String mValue = (String)mValueField.get(this);
boolean mValueSet = (boolean)mValueSetField.get(this);
boolean changed = !TextUtils.equals(mValue, value);
if(changed || !mValueSet)
{
mValueField.set(this, value);
mValueSetField.set(this, mValueSet);
this.persistInt(Integer.parseInt(value));
if(changed) {
this.notifyChanged();
}
}
}
catch (NoSuchFieldException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
}
值,只需尝试一下即可。它可能会立即工作,或者您可能需要覆盖其他功能。如果是这样,这是一个良好的开端,并向您展示如何做到这一点......