Android:自定义视图,键入"类"数字键盘(IME)-输入不';行不通

Android:自定义视图,键入"类"数字键盘(IME)-输入不';行不通,android,android-custom-view,android-keypad,Android,Android Custom View,Android Keypad,当我将键盘类型设置为键入类号时,我遇到了一种奇怪的键盘行为 我使用BaseInputConnection连接我的可编辑对象和TextWathcer以监听任何文本更改 问题是: 当inputType=TYPE\u CLASS\u文本且第一个输入符号为any时 除数字外的符号-所有工作正常,可编辑文本更改 当我将键盘类型切换为键入\u CLASS\u NUMBER并尝试 输入数字-没有任何变化 例如: 输入“12345”输出“” 输入“teststring123”输出“teststring123”

当我将键盘类型设置为键入类号时,我遇到了一种奇怪的键盘行为

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

问题是:

  • 当inputType=TYPE\u CLASS\u文本且第一个输入符号为any时 除数字外的符号-所有工作正常,可编辑文本更改

  • 当我将键盘类型切换为键入\u CLASS\u NUMBER并尝试 输入数字-没有任何变化

  • 例如:

  • 输入“12345”输出“”
  • 输入“teststring123”输出“teststring123”
  • 输入“123teststring”输出“teststring”
  • 完整代码:

    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();
        }
    }
    }
    

    好的,我找到了解决办法,对我来说很有效

    要处理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);
            }
         };
     }
    
    @覆盖
    公共输入连接onCreateInputConnection(EditorInfo outAttrs){
    outAttrs.inputType=inputType.TYPE\类别\编号;
    outAttrs.imeOptions=EditorInfo.IME\u操作\u完成;
    outAttrs.initialSelStart=0;
    outAttrs.initialSelEnd=0;
    返回新的BaseInputConnection(this,true){
    @凌驾
    公共可编辑getEditable(){
    返回可编辑;
    }
    @凌驾
    公共布尔值endBatchEdit(){
    批处理++;
    返回super.endBatchEdit();
    }
    @凌驾
    公共布尔值beginBatchEdit(){
    批次--;
    返回super.beginBatchEdit();
    }
    @凌驾
    公共布尔sendKeyEvent(KeyEvent事件){
    如果(event.getAction()==KeyEvent.ACTION\u向下
    &&event.getKeyCode()>=KeyEvent.KEYCODE\u 0
    
    &&event.getKeyCode()好的,我找到了适合我的解决方案

    要处理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);
            }
         };
     }
    
    @覆盖
    公共输入连接onCreateInputConnection(EditorInfo outAttrs){
    outAttrs.inputType=inputType.TYPE\类别\编号;
    outAttrs.imeOptions=EditorInfo.IME\u操作\u完成;
    outAttrs.initialSelStart=0;
    outAttrs.initialSelEnd=0;
    返回新的BaseInputConnection(this,true){
    @凌驾
    公共可编辑getEditable(){
    返回可编辑;
    }
    @凌驾
    公共布尔值endBatchEdit(){
    批处理++;
    返回super.endBatchEdit();
    }
    @凌驾
    公共布尔值beginBatchEdit(){
    批次--;
    返回super.beginBatchEdit();
    }
    @凌驾
    公共布尔sendKeyEvent(KeyEvent事件){
    如果(event.getAction()==KeyEvent.ACTION\u向下
    &&event.getKeyCode()>=KeyEvent.KEYCODE\u 0
    &&event.getKeyCode()