如何创建仅接受整数值的首选项

Gia*_*nzi 11 android android-preferences android-edittext

有没有办法在PreferenceFragment中创建只接受整数值的首选项?我可以实现一个EditTextPreference并注册一个OnPreferenceChangeListener,如果用户输入一个不是数字的字符串,我可以拒绝更改,但我更喜欢那些仅用于保存数字而且不允许用户输入任何其他内容的字符串,也许只显示拨号盘键盘..我不存在这样的偏好,因为Preference的每个后代都映射到布尔值(CheckBoxPreference),String(*EditTextPreference)或String数组(MultiSelectListPreference),即有没有偏好映射到整数,但也许你们中的一些人可以给我一个提示或至少告诉我是否有比我上面提出的解决方案更好的解决方案.

Gray提出的解决方案:

EditText editText = ((EditTextPreference)    
                             findPreference("intent_property")).getEditText();
editText.setKeyListener(new NumberKeyListener() {
    @Override
    public int getInputType() {
        // The following shows the standard keyboard but switches to the view 
        // with numbers on available on the top line of chars
        return InputType.TYPE_CLASS_NUMBER;
        // Return the following to show a dialpad as the one shown when entering phone
        // numbers.
        // return InputType.TYPE_CLASS_PHONE
    }

    @Override
    protected char[] getAcceptedChars() {
        return new String("1234567890").toCharArray();
    }
});
Run Code Online (Sandbox Code Playgroud)

更短的解决方案,不允许将键盘改为拨号盘,但需要的代码更少:

EditText editText = ((EditTextPreference) 
                             findPreference("intent_property")).getEditText();
editText.setKeyListener(new DigitsKeyListener());
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个解决方案的一件事:用户可以输入0000并将其接受并保存在共享首选项(这是一个字符串)中为"0000"..这要求您实现一个OnSharedPreferenceChangeListener来拦截对共享首选项并删除此首选项中的前导零或直接在此首选项上实现更改侦听器并返回false以拒绝带有尾随零的数字(告诉我是否有更好的解决方案来解决此问题,而不涉及实现您自己的首选项).这将是美的,如果我们可以修改NEWVALUEOnPreferenceChangeListener ..

Too*_*oop 31

有一种更简单的方法可以做到这一点.只需在XML中的EditTextPreference中设置android:numeric ="integer"(可以将其设置为整数,有符号或十进制).

Eclipse(或您正在使用的任何工具)不会将此作为可能的属性显示,但只需将其写入EditTextPreference并清理项目即可.你会发现它不会给你任何错误.:)


MH.*_*MH. 6

在阅读了提议的解决方案后,我仍然认为自定义偏好是可行的方法.我确实以粗体文本阅读了您的评论,但设置基本EditTextIntegerPreference实际上非常简单,它将解决用户输入例如"0000"时的剩余问题.

请注意:由于您通常希望能够在应用程序的多个位置使用首选项,因此就我而言,正确实现a EditTextIntegerPreference会将其值存储在Integer.这样你就可以在任何地方检索int值,而无需先解析或转换它.

但是,为了保持这个答案的重点和紧凑,我实际上将展示一个常规的扩展EditTextPreference,这意味着在引擎盖下,该值仍将存储为字符串.如果你真的热衷于让'正确'的实现工作,我不介意以后写这个.它应该不是太棘手,所以你可能想先自己解决一下.:)

public class EditTextIntegerPreference extends EditTextPreference {

    private Integer mInteger;

    public EditTextIntegerPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
    }

    public EditTextIntegerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
    }

    public EditTextIntegerPreference(Context context) {
        super(context);
        getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
    }

    @Override public void setText(String text) {
        final boolean wasBlocking = shouldDisableDependents();
        mInteger = parseInteger(text);
        persistString(mInteger != null ? mInteger.toString() : null);
        final boolean isBlocking = shouldDisableDependents(); 
        if (isBlocking != wasBlocking) notifyDependencyChange(isBlocking);
    }

    @Override public String getText() {
        return mInteger != null ? mInteger.toString() : null;
    }

    private static Integer parseInteger(String text) {
        try { return Integer.parseInt(text); }
        catch (NumberFormatException e) { return null; }
    }    
}
Run Code Online (Sandbox Code Playgroud)

解决"0000"问题的原因是我们在存储之前只是将用户输入的值转换为int,并在检索时将其插回到字符串中.这意味着任何前导零(除了'0'作为一个过程)将自动消失.

'number'输入类型将限制用户仅输入输入数字,因此该parseInteger(...)方法主要出于理智原因,但NumberFormatException如果您尝试输入空或null字符串,它将捕获a .再说一次,你可以把它变得更漂亮,这是我现在还没有做过的.