2011-03-08 26 views
23

我在共享首选项中创建列表,并调用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,布尔值或枚举值的列表。习惯性的做法是什么?

在此先感谢,

周杰伦

回答

40

把喜好为String和使用Integer.parseInt()。我认为实际上有一个关于您提到的限制的错误报告,但我找不到链接。根据经验,我可以告诉你只需使用Strings,并为自己节省很多挫折。

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

+0

那么这是一种讨厌。 – theblang 2014-02-13 17:32:46

10

安德鲁是正确的,线程是here

它仍然被评论,却没有任何变化(如2.3.3反正)。

.valueOf()的Integer.parseInt()必须工作。如果valueOf()在没有错误的情况下工作,那么使用它,因为它不像parseInt()那样分配多少,所以当你需要像我一样避免GC时有用。

+0

我觉得你很迷惑valueOf()和parseInt()。请注意,valueOf()在内部实现为:new Integer(Integer.parseInt(i)); //虽然有一些缓存 – auval 2013-11-03 20:35:05

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> 
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值,只是试一试。它可能马上工作,或者您可能需要重写其他功能。如果是这样,这是一个好的开始,并告诉你如何做到这一点...