PreferenceActivity:将值保存为整数

Posted

技术标签:

【中文标题】PreferenceActivity:将值保存为整数【英文标题】:PreferenceActivity: save value as integer 【发布时间】:2011-04-12 21:22:14 【问题描述】:

在我的偏好活动中使用简单的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默认将值保存为整数?

【问题讨论】:

【参考方案1】:

您可以扩展 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"
/>

【讨论】:

@Brutall,我想通过改进代码来感谢你。但是有人跟我说新代码……太长了,他拒绝了。哦,但是如果旧代码不好,需要更换,但人们不这样做,因为新代码……长,人们会怎么做?即使它更好。哦,天哪,太棒了!这是程序员的地方?我有一些开源项目,我愿意对我的代码进行任何更改。让他多么丢脸!无论如何,非常感谢你,布鲁托。 顺便说一句,我所做的就是:将输入类型设置为数字;添加TextWatcher,确保用户输入的文本不为空,默认值为0 我在return String.valueOf(getPersistedInt(-1)); 上遇到运行时错误,由于该行而无法启动活动 @user942821 但是没有默认类型 int 的首选项吗?这太疯狂了,它不仅存在,还需要所有这些额外的代码。为什么默认没有“EditIntPreference”标签? @user942821 这很烦人,因为我只想公开一些内部整数首选项以进行调试,它们通常甚至不是用户应该编辑的!【参考方案2】:

即使您设置了 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);

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

【讨论】:

我在哪里可以覆盖它?默认情况下PreferenceActivity会自动保存,我应该重写一些获取值的方法还是全部保存自己? 好的,更改偏好类型不好,因为您可能会遇到 ClassCastException 问题。我已经更新了我的答案。 是的,我自己也考虑过 wrapper,但我还是不喜欢这个解决方案……SharedPreferences 已经有getInt 方法,所以仍然希望以某种方式找到一种方法来告诉PreferenceActivity 将值保存为 int - 所有功能都在那里......只是不能按预期工作...... 你总是可以编写自己的 Preference 类。 OP 已询问如何将值保存为整数。这个答案没有解决这个问题,它只是提供了一种解决方法,可以在保存 STRING 的同时取回 Integer。【参考方案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" />

【讨论】:

如果你希望值被持久化为“int”,即你想使用preferences.getInt()来加载首选项,你需要使用接受的答案。 2019 更新:android:numeric 现已弃用,您应该改用 android:inputType="number"【参考方案4】:

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

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

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

int number = Integer.valueOf(settings.getString("myNumberString", "0"));

【讨论】:

【参考方案5】:

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

int CheckInterval = Integer.parseInt(sharedPreferences.getString("check_frequency","60"));

【讨论】:

【参考方案6】:

我知道这是一个已被接受的答案的老问题,但我认为我的解决方案可能对寻找更完整答案的人有所帮助。我刚刚改进了@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.OnBindEditTextListener 在自定义 EditTextPreference 中设置输入类型,如上面的代码所示。

这对我有用。

【讨论】:

以上是关于PreferenceActivity:将值保存为整数的主要内容,如果未能解决你的问题,请参考以下文章

Android之设置页面(PreferenceActivity使用)

在 API 15 及更高版本中使用 PreferenceActivity

在 PreferenceActivity 中启用和禁用选项

android中SharedPreferences和PreferenceActivity的存取数据

您如何刷新 PreferenceActivity 以显示设置的更改?

PreferenceActivity 中的 ActionBar