开发者

What does KeyListener do exactly?

If I'm right, there is a bug that when the locale says the decimal point is comma (as in Germany or Italy), Android's numeric keyboad does not accept entering commas. It still only accetps dots. I must fix this bug in my app. Requirements are:

  1. When focus is set to an EditText, the program brings up the soft keyboard in symbol/numeric mode.
  2. When under European locales, the keyboard accepts a comma (and a sign).
  3. And, #2 must be done programmatically.

I find that I can use XML to achieve #1 and #2 (althgout it'd allow mutiple signs and decimal points in the intput), bu开发者_如何学Pythont it doesn't satisfy #3:

android:inputType="numberDecimal|numberSigned"
android:digits="1234567890,-"

Documentation says android:digits can be acheieved by using KeyListener. So I did a KeyListener to allow/disallow characters. But from what I saw, no matter what I return from onKeyDown(), the input character is always allowed. I expect KeyListener() allows me to filter the input, but I must have missed something. Could you please point it out? Thank you!

et.setKeyListener(new KeyListener() {
    @Override public void clearMetaKeyState(View view, Editable content, int states) {} 
    @Override public int getInputType() {  return InputType.TYPE_CLASS_NUMBER; }
    @Override public boolean onKeyDown(View view, Editable text, int keyCode, KeyEvent event) {
        if ((keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) ||
            keyCode == KeyEvent.KEYCODE_MINUS || 
            keyCode == KeyEvent.KEYCODE_COMMA) {
            // I want to allow these
            return false;
        }
        // I want to disallow the rest
        return true;
    }
    @Override public boolean onKeyOther(View view, Editable text, KeyEvent event) { return false; }
    @Override public boolean onKeyUp(View view, Editable text, int keyCode, KeyEvent event) { return false; }
});

P.S: I've also tried to use et.setFilters() and give it a custom InputFilter. But it seems that as long as android:inputType="numberDecimal" exists, which I need to set keyboard to number/symbol mode, it ignores my filter.

final int decimalPoint = ',';
InputFilter[] filterArray = new InputFilter[1];  
filterArray[0] = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) 
    {
        int dots = 0, i;
        String s = source.toString();
        String d = dest.toString();
        boolean hasSign = false;

        if (source.length() == 0)
            return null;

        for (i = 0; i < d.length(); i++)
            if (d.charAt(i) == '-')
                hasSign = true;
            else if (d.charAt(i) == decimalPoint)
                dots++;
        for (i = start; i < end && i < s.length(); i++) {
            if ((s.charAt(i) >= '0' && s.charAt(i) <= '9') ||
                (s.charAt(i) == '-' && !hasSign && i == start && d.length() == 0))
                continue;
            if (s.charAt(i) == decimalPoint && dots == 0) {
                dots++;
                continue;
            }
            s = s.substring(0, start) + s.substring(start + 1, end);
            end--;
        }
        return s.length() == source.length() ? null : s;
    }};
et.setFilters(filterArray);


This should do the trick.

et.setKeyListener(DigitsKeyListener.getInstance("1234567890,-"));


Everything you need to know about KeyListener is here

Hope that assists you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜