51

EditTextPreference在我的偏好活动中使用简单的:

<EditTextPreference
    android:key="SomeKey"
    android:title="@string/some_title"
    android:summary="..."
    android:numeric="integer"
    android:maxLength="2"
/>

有没有办法将此配置值保存为整数?现在似乎它只允许输入数字,但该值仍保存为字符串:

来电:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int value = preferences.getInt("SomeKey", -1);

抛出我java.lang.ClassCastException: java.lang.String,并且:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String value = preferences.getString("SomeKey", "-1");

成功检索值。

默认情况下如何PreferenceActivity将值保存为整数?

4

6 回答 6

71

您可以扩展 EditTextPreference:

public class IntEditTextPreference extends EditTextPreference {

    public IntEditTextPreference(Context context) {
        super(context);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected String getPersistedString(String defaultReturnValue) {
        return String.valueOf(getPersistedInt(-1));
    }

    @Override
    protected boolean persistString(String value) {
        return persistInt(Integer.valueOf(value));
    }
}

覆盖 onSetInitialValue() 和 setText() 方法会更好,但是您必须从基类中复制一些代码。上面的解决方案更简单,但它非常棘手 - “字符串”方法对整数做一些事情。尽量不要进一步扩展这个类;-)

您可以通过以下方式从 XML 中使用它:

<package.name.IntEditTextPreference
    android:key="SomeKey"
    android:title="@string/some_title"
    android:summary="..."
    android:numeric="integer"
    android:maxLength="2"
/>
于 2010-09-20T21:22:11.157 回答
6

即使您设置了 android:numeric="integer" ,它也会是文本首选项 - 正如它的名字所暗示的那样。您可以使用 Integer.valueOf() 轻松地将字符串值转换为 int。您也可以覆盖 PreferenceActivity 以在退出时自动进行转换。


我认为最好的解决方案是编写简单的方法来从偏好中获取这个值。就像是:

public static int getSomePref(Context context) {
    SharedPreferences prefs =
        PreferenceManager.getDefaultSharedPreferences(context);
    String value = prefs.getString("SomeKey", null);
    return value == null ? -1 : Integer.valueOf(value);
}

然后你可以很容易地从你的代码中使用它。

于 2010-09-15T22:16:32.257 回答
3

即使一个答案已被接受,我还是想分享一种更短的方法来实现这一点:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int value = Integer.parseInt(preferences.getString("SomeKey", "-1"));

由于您已经设置了只能输入数字,因此不会出现任何异常。尚未完成我的回答:

<EditTextPref
    android:key="SomeKey"
    android:title="@string/some_title"
    android:summary="..."
    android:numeric="integer"
    android:maxLength="2" />
于 2016-01-18T10:25:08.093 回答
0

我有同样的问题。(我希望 SharedPreference 给我一个端口号,我将其作为 defaultValue 存储在首选项 xml 文件中)。

实现所有 SharedPreferences 方法会很费力,所以我认为最好在类中编写一个实例化 SharedPreferences 的自定义方法,正如broot建议的那样。

您也可以在需要的行中使用 Integer 的 Static 方法:

int number = Integer.valueOf(settings.getString("myNumberString", "0"));
于 2016-01-18T09:58:03.317 回答
0

我认为这是我能想到的最短的一个:

int CheckInterval = Integer.parseInt(sharedPreferences.getString("check_frequency","60"));
于 2019-03-16T09:12:58.337 回答
0

我知道这是一个已被接受的答案的老问题,但我认为我的解决方案可能对寻找更完整答案的人有所帮助。我刚刚改进了@broot 的回答,我的解决方案就这样:

覆盖 EditTextPreference 以提供文本到 int 的转换:

public class IntEditTextPreference extends EditTextPreference implements EditTextPreference.OnBindEditTextListener {
    private String mText;
    
    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        setOnBindEditTextListener(this);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setOnBindEditTextListener(this);
    }

    public IntEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOnBindEditTextListener(this);
    }

    public IntEditTextPreference(Context context) {
        super(context);
        setOnBindEditTextListener(this);
    }

    /**
     * Saves the text to the current data storage.
     *
     * @param text The text to save
     */
    public void setText(String text) {
        final boolean wasBlocking = shouldDisableDependents();

        mText = text;

        int value = Integer.parseInt(text);

        persistInt(value);

        final boolean isBlocking = shouldDisableDependents();
        if (isBlocking != wasBlocking) {
            notifyDependencyChange(isBlocking);
        }

        notifyChanged();
    }

    /**
     * Gets the text from the current data storage.
     *
     * @return The current preference value
     */
    public String getText() {
        return mText;
    }

    @Override
    protected void onSetInitialValue(Object defaultValue) {
        int value;
        if (defaultValue != null) {
            String strDefaultValue = (String) defaultValue;

            int defaultIntValue = Integer.parseInt(strDefaultValue);
            value = getPersistedInt(defaultIntValue);
        } else {
            value = getPersistedInt(0);
        }

        setText(Integer.toString(value));
    }

    @Override
    public boolean shouldDisableDependents() {
        return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
    }

    @Override
    public void onBindEditText(@NonNull EditText editText) {
        editText.setInputType(InputType.TYPE_CLASS_NUMBER);
    }
}

在首选项 xml 中:

<your.package.here.IntEditTextPreference
            android:key="some_key"
            android:title="@string/some_title"
            android:defaultValue="5"
            app:useSimpleSummaryProvider="true"/>

注意:不要使用 android:numeric 或 android:inputType。由于 EditTextPreference 不是 EditText 本身,因此设置这些属性将无济于事。为了从 EditTextPreference 打开的 Dialog 中达到所需的 EditText 效果,只需通过实现在您的自定义 EditTextPreference 中设置输入类型,EditTextPreference.OnBindEditTextListener如您在上面的代码中所见。

这对我有用。

于 2021-02-13T17:54:00.223 回答