美文网首页
EditText输入手机号中间自动追加空格

EditText输入手机号中间自动追加空格

作者: 不会弹钢琴de大叔 | 来源:发表于2020-06-16 16:11 被阅读0次

    最近项目中需要实现类似银行卡输入4位有空格的输入格式,在网上查找发现大部分的都有bug,虽然能实现,但是会出现各种bug(比如在中间删除,空格就你懂得了)。

    没办法只能自己查找资料,研究代码。大部分人都是对edittext添加addTextChangedListener,监听textwatcher,但是这个监听要想明白,这个是edittext已经修改完成了,通知你的地方,并不能直接限制edittext的输入,所以我就想到了需要去edittext的源码看看。

    研究了源码我们需要,重写edittext,在edittext的方法中有onCreateInputConnection方法,这个方法就是控制输入的能有效拦截输入的内容。

    话不多说上代码:通过下述代码可以实现输入电话号自动空格,并且不能粘贴复制,可以在任意位置进行删除,插入,不会影响空格位置(网上大部分都不能实现),如果需要银行卡空格的设置,在这个基础上可以修改就是控制字符的位置即可。代码还实现了控制粘贴和复制的操作防止通过粘贴设置值导致出错
    .............................

    public class PhoneLimitEditText extends AppCompatEditText {
        private static final String TAG = PhoneLimitEditText.class.getSimpleName();
        private static final int NUM_13 = 13;
        private static final int NUM_3 = 3;
        private static final int NUM_7 = 7;
        private static final int NUM_8 = 8;
        private int tempSelect = 0;
        private boolean isTextChange = false;
    
        public PhoneLimitEditText(Context context) {
            super(context);
            init();
        }
    
        public PhoneLimitEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public PhoneLimitEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            disableCopyAndPaste();
        }
    
        /**
         * ime
         *
         * @param outAttrs
         */
        @Override
        public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
            return new mInputConnection(super.onCreateInputConnection(outAttrs), true);
        }
    
        @Override
        protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
            super.onTextChanged(text, start, lengthBefore, lengthAfter);
            Log.i(TAG, "onTextChanged: " + text);
            if (isTextChange) {
                isTextChange = false;
                return;
            }
            if (lengthBefore > 0) {
                if (tempSelect <= text.length()) {
                    calcTabText(text);
                }
            } else if (lengthAfter > 0) {
                if (getSelectionStart() < text.length()) {
                    calcTabText(text);
                }
            }
            if (text.toString().endsWith(" ")) {
                getEditableText().delete(text.length() - 1, text.length());
            }
        }
    
        /**
         * calc text add tab.
         *
         * @param text editText content.
         */
        private void calcTabText(CharSequence text) {
            isTextChange = true;
            String tempText = text.toString().replace(" ", "");
            StringBuilder stringBuilder = new StringBuilder(tempText);
            if (tempText.length() > NUM_3) {
                stringBuilder.insert(NUM_3, " ");
            }
            if (tempText.length() > NUM_7) {
                stringBuilder.insert(NUM_8, " ");
            }
            getEditableText().replace(0, text.length(), stringBuilder);
            setSelection(getEditableText().length());
        }
    
        class mInputConnection extends InputConnectionWrapper implements InputConnection {
            public mInputConnection(InputConnection target, boolean mutable) {
                super(target, mutable);
            }
    
            @Override
            public boolean commitText(CharSequence text, int newCursorPosition) {
                if (" ".equals(text.toString())) {
                    return super.commitText("", newCursorPosition);
                }
                if (!text.toString().matches("[0-9]")) {
                    return false;
                }
                int length = getEditableText().length();
                if (length == NUM_13) {
                    return false;
                }
                if (length == NUM_3 || length == NUM_8) {
                    text = " " + text;
                }
                return super.commitText(text, newCursorPosition);
            }
    
            @Override
            public boolean sendKeyEvent(KeyEvent event) {
                if (event.getKeyCode() == KeyEvent.KEYCODE_TAB) {
                    return false;
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                    if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        tempSelect = getSelectionStart();
                    }
                }
                return super.sendKeyEvent(event);
            }
        }
    
        /**
         * cancel copy & pause.
         */
        public void disableCopyAndPaste() {
            try {
                setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        return true;
                    }
                });
                setLongClickable(false);
                setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (event.getAction() == MotionEvent.ACTION_DOWN) {
                            // setInsertionDisabled when user touches the view
                            setInsertionDisabled();
                        }
                        return false;
                    }
                });
                setCustomSelectionActionModeCallback(new ActionMode.Callback() {
                    @Override
                    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                        return false;
                    }
    
                    @Override
                    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                        return false;
                    }
    
                    @Override
                    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                        return false;
                    }
    
                    @Override
                    public void onDestroyActionMode(ActionMode mode) {
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        private void setInsertionDisabled() {
            try {
                Field editorField = TextView.class.getDeclaredField("mEditor");
                editorField.setAccessible(true);
                Object editorObject = editorField.get(this);
                  // if this view supports insertion handles
                Class editorClass = Class.forName("android.widget.Editor");
                Field mInsertionControllerEnabledField =
                        editorClass.getDeclaredField("mInsertionControllerEnabled");
                mInsertionControllerEnabledField.setAccessible(true);
                mInsertionControllerEnabledField.set(editorObject, false);
                // if this view supports selection handles
                Field mSelectionControllerEnabledField =
                        editorClass.getDeclaredField("mSelectionControllerEnabled");
                mSelectionControllerEnabledField.setAccessible(true);
                mSelectionControllerEnabledField.set(editorObject, false);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }}
    

    ......................................

    感觉不错就点赞支持一下吧O(∩_∩)O~

    相关文章

      网友评论

          本文标题:EditText输入手机号中间自动追加空格

          本文链接:https://www.haomeiwen.com/subject/tydrxktx.html