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

最近项目中需要实现类似银行卡输入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输入手机号中间自动追加空格)