Development Tip

ListPreference : 항목 값으로 문자열 배열을 사용하고 항목 값이 작동하지 않으므로 정수 배열을 사용합니다.

yourdevel 2020. 11. 5. 19:22
반응형

ListPreference : 항목 값으로 문자열 배열을 사용하고 항목 값이 작동하지 않으므로 정수 배열을 사용합니다.


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항목과 항목 값 모두에 배열을 사용 하기 만하면 됩니다. 그리고이 메서드를 사용하여 a String로 쉽게 변환 할 수 있기 때문에이 사실에서 어떤 문제도 볼 수 없습니다 . 도움이 되었기를 바랍니다.intInteger.parseInt()


답변은 List Preference Documentation에 나와 있습니다 .

int findIndexOfValue (String value)

주어진 값에 대한 인덱스를 반환하고 인수는 문자열로 취하므로이 작업을 얻으려면 entryValues ​​배열이 문자열 배열이어야합니다.


입력 값을 문자열로 변환하여 ListPreference만족스러운 상태를 유지 한 다음 int영구 데이터 저장소와 통신 할 때 s 로 변환 할 수 있습니다.

  1. 항목 값을 설정하는 경우, 대신 int 치의 문자열을 사용 : "1", "2", "3"
  2. Make a custom IntListPreference that persists the values as ints
  3. In your preferences.xml file, change the <ListPreference> into a <your.app.package.IntListPreference>

IntListPreference.java

Here's a sample implementation. Tested and working on 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;
}

참고URL : https://stackoverflow.com/questions/11346916/listpreference-use-string-array-as-entry-and-integer-array-as-entry-values-does

반응형