Android:使用TYPE_CLASS_NUMBER键盘(IME)的自定义视图 - 输入无效

时间:2017-06-21 00:03:51

标签: android android-custom-view android-keypad

当我将键盘类型设置为TYPE_CLASS_NUMBER时,我遇到了奇怪的键盘行为。

我使用BaseInputConnection连接我的可编辑对象和TextWathcer来监听任何文本更改。

问题:

  1. 当inputType = TYPE_CLASS_TEXT且第一个输入符号为any时 除了数字之外的符号 - 所有工作都很好并且可以编辑文本。

  2. 当我将键盘类型切换为TYPE_CLASS_NUMBER并尝试时 输入数字 - 没有任何变化。

  3. 例如:

    1. 输入" 12345"输出""
    2. 输入" teststring123"输出" teststring123" ,
    3. 输入" 123teststring"输出" teststring"
    4. 完整代码:

      public class CustomView extends View implements View.OnClickListener {
      
      private Editable editable;
      
      private InputMethodManager imm;
      
      private final CustomTextWatcher textWatcher = new CustomTextWatcher();
      
      private Paint mainPaint;
      
      private int batch;
      
      public CustomView(Context context) {
          super(context);
          init(context, null);
      }
      
      public CustomView(Context context, @Nullable AttributeSet attrs) {
          super(context, attrs);
          init(context, attrs);
      }
      
      public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
          init(context, attrs);
      }
      
      private void init(Context context, @Nullable AttributeSet attrs) {
      
          setOnClickListener(this);
          setFocusableInTouchMode(true);
          imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
      
          editable = Editable.Factory.getInstance().newEditable("");
          editable.setSpan(textWatcher, 0, editable.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
          Selection.setSelection(editable, 0);
      
      
          mainPaint = new Paint();
          mainPaint.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
          mainPaint.setTextSize(30);
      }
      
      @Override
      protected void onDraw(Canvas canvas) {
          canvas.drawText(editable.toString(), 15, 20, mainPaint);
          super.onDraw(canvas);
      }
      
      @Override
      public void onClick(View v) {
          imm.showSoftInput(this, 0);
      }
      
      @Override
      public boolean onTouchEvent(MotionEvent event) {
          if (event.getAction() == MotionEvent.ACTION_UP && batch == 0) {
              int cursorPosition = 0;
      
              imm.viewClicked(this);
              imm.updateSelection(this, cursorPosition, cursorPosition, cursorPosition, cursorPosition);
              imm.updateSelection(this, cursorPosition, cursorPosition, -1, -1);
          }
          return super.onTouchEvent(event);
      }
      
      @Override
      public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
          Log.e("CustomView", " onCreateInputConnection");
      
          outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
          outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
          outAttrs.initialSelStart = 0;
          outAttrs.initialSelEnd = 0;
      
          return new BaseInputConnection(this, true) {
              @Override
              public Editable getEditable() {
                  return editable;
              }
      
              @Override
              public boolean endBatchEdit() {
                  batch++;
                  return super.endBatchEdit();
              }
      
              @Override
              public boolean beginBatchEdit() {
                  batch--;
                  return super.beginBatchEdit();
              }
          };
      }
      
      @Override
      public boolean onCheckIsTextEditor() {
          return true;
      }
      
      
      private class CustomTextWatcher implements TextWatcher {
      
          @Override
          public void beforeTextChanged(CharSequence s, int start, int count, int after) {
          }
      
          @Override
          public void onTextChanged(CharSequence s, int start, int before, int count) {
      
          }
      
          @Override
          public void afterTextChanged(Editable s) {
              Log.e("CustomView",  "afterTextChanged " + s);
              invalidate();
          }
      }
      }
      

1 个答案:

答案 0 :(得分:0)

好的,我找到了适合我的解决方案。

要处理来自IME的数字并通过InputConnection将它们传递给可编辑对象,您只需执行以下操作:

实现“sendKeyEvent”方法,如下所示

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {

    outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
    outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
    outAttrs.initialSelStart = 0;
    outAttrs.initialSelEnd = 0;

    return new BaseInputConnection(this, true) {

        @Override
        public Editable getEditable() {
            return editable;
        }

        @Override
        public boolean endBatchEdit() {
            batch++;
            return super.endBatchEdit();
        }

        @Override
        public boolean beginBatchEdit() {
            batch--;
            return super.beginBatchEdit();
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {

            if(event.getAction() == KeyEvent.ACTION_DOWN 
                     && event.getKeyCode() >= KeyEvent.KEYCODE_0 
                     && event.getKeyCode() <= KeyEvent.KEYCODE_9) {
                char c = event.getKeyCharacterMap().getNumber(event.getKeyCode());
                commitText(String.valueOf(c), 1);
            }
            return super.sendKeyEvent(event);
        }
     };
 }