24

我在共享首选项中创建列表,当调用 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 不起作用。我知道如何使用字符串数组而不是值数组来做到这一点。而且我可以提取值字符串并从中得出我想要的东西,但我宁愿(如果可能的话)能够拥有值是整数、布尔值或枚举的列表。这样做的习惯方法是什么?

提前致谢,

周杰伦

4

4 回答 4

41

将首选项放入 asString并使用Integer.parseInt()。我认为实际上有一个关于您所指的限制的错误报告,但我找不到链接。根据经验,我可以告诉你只是使用Strings并节省你自己的很多挫折感。

请注意其他 SO 用户,如果您能证明我错了,我欢迎它。

于 2011-03-08T02:05:13.810 回答
10

安德鲁是正确的,线程在这里

它仍在评论中,但没有任何变化(无论如何从 2.3.3 开始)。

.valueOf() 的 Integer.parseInt() 必须起作用。如果 valueOf() 正常工作,请使用它,因为它分配的空间不如 parseInt() 多,当您需要像我一样避免 GC 时会很有帮助。

于 2011-04-21T01:00:21.093 回答
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>
于 2013-11-30T01:13:23.687 回答
0

这是ListIntegerPreference我使用的一个类(为 编写com.android.support:preference-v7:24.0.0)。它覆盖了一些方法并在可能的情况下在两者之间进行转换IntegerString以使基础ListPreference无法识别您正在使用的方法Integers而不是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();
        }
    }
}

我正在使用它来ListPreferences通过代码创建值,试试吧。它可能会立即工作,或者您可能需要覆盖其他功能。如果是这样,这是一个好的开始,并向您展示如何做到这一点......

于 2016-07-05T20:28:27.243 回答