簡體   English   中英

ListPreference:使用字符串數組作為條目,使用整數數組作為條目值不起作用

[英]ListPreference: use string-array as Entry and integer-array as Entry Values doesn't work

我在settings.xml文件中使用ListPreference。 我想向用戶顯示3個選項列表。 當用戶在“設置”中選擇一個選項時,出現此錯誤:

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)

這是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" />

這是我用來填充條目的數組:

<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>

在我的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;
        }
}

如果我對entryValues使用另一個字符串數組,它將起作用。 例如,如果我使用相同的字符串數組作為值和條目:

    android:entries="@array/date_alignement"
    android:entryValues="@array/date_alignement"

然后我必須稍微修改一下代碼,但它可以工作:

        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;
        }

為什么我不能對ListPreference條目和值使用字符串數組和整數數組?

答案很簡單:因為Android是按這種方式設計的。 它僅將String數組用於條目和條目值,僅此而已。 而且我看不到任何問題,因為您可以使用Integer.parseInt()方法輕松地將String轉換為int 希望這可以幫助。

答案在“ 列表首選項文檔”列出

int findIndexOfValue (String value)

將返回給定值的索引,並且參數作為字符串使用,因此entryValues數組應為字符串數組才能完成此工作。

您可以將輸入值轉換為字符串,以使ListPreference滿意,然后在與持久數據存儲區通信時將其轉換為int

  1. 設置條目值時,請使用字符串而不是整數: "1", "2", "3"
  2. 創建一個自定義的IntListPreference ,將值持久保存為int
  3. 在您的preferences.xml文件中,將<ListPreference>更改為<your.app.package.IntListPreference>

IntListPreference.java

這是一個示例實現。 經過測試並在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);
    }

}

以下為我工作:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM