输入时候动态的让银行卡格式化
1.目前已知长按粘贴会有部分bug, 暂时没有解决, 统一处理是把光标放到最后.
2.无法长按删除, 猜测是 format(String.valueOf(editable)); 方法后删除按钮的焦点消失, 暂时没解决.
/** * 选中一个粘贴一个(光标停留在粘贴元素最后一个) * 选中一个删除 (光标停留在删除掉的元素的start位置) * 选中一个粘贴多个(光标停留在粘贴元素最后一个) * * 选中多个粘贴相同数量 (光标停留在粘贴元素最后一个) * 选中多个粘贴少量(光标停留在粘贴元素最后一个) * 选中多个粘贴更多(光标停留在粘贴元素最后一个) */
/** * Created by sqj on 2017/12/5. */ public class BankIDFormatEditText extends EditText { String space = " "; private boolean shouldStopChange = false; private int textOnViewLength; private String mTextBefore; private String mTextAfter; private int mStartPosition; private int mEndPosition; public BankIDFormatEditText(Context context) { this(context, null); } public BankIDFormatEditText(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BankIDFormatEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { setFocusable(true); setEnabled(true); setFocusableInTouchMode(true); addTextChangedListener(new BandCardWatcher()); } private class BandCardWatcher implements TextWatcher { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { if (shouldStopChange) { } else { mTextBefore = String.valueOf(s); mStartPosition = getSelectionStart(); mEndPosition = getSelectionEnd(); // 第一次改变后总长度(手输) mBeforeChangeLength = s.toString().length(); } } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // Log.d("BandCardWatcher", "onTextChanged:" + s); } @Override public void afterTextChanged(Editable editable) { if (shouldStopChange) { shouldStopChange = false; return; } shouldStopChange = true; mTextAfter = String.valueOf(editable); if (mStartPosition!=mEndPosition){// 这是长按选中的状态 format(editable); setSelection(textOnViewLength); }else { if (mTextBefore.length() < mTextAfter.length()) {// 增加 format(editable); if ((mStartPosition + 1) % 5 == 0) { if (mStartPosition != 0) { setSelection(mStartPosition + 2); } } else { setSelection(mStartPosition + 1); } } else if (mTextBefore.length() > mTextAfter.length()) { // 减少 if (mStartPosition % 5 == 0) { if (mStartPosition != 0) { // 光标在空格后面点删除的情况 editable.replace(mStartPosition - 2, mStartPosition - 1, " "); } } format(editable); if (mStartPosition != 1 && (mStartPosition - 1) % 5 == 0) { setSelection(mStartPosition - 2); } else if (mStartPosition != 0) { setSelection(mStartPosition - 1); } } else if (mTextBefore.length() == mTextAfter.length()) {// 替换 format(editable); setSelection(mStartPosition); } } } } private void format(Editable editable) { String str = editable.toString().trim().replaceAll(space, ""); int len = str.length(); int courPos; StringBuilder builder = new StringBuilder(); for (int i = 0; i < len; i++) { if (i % 4 == 0 && i != 0) { builder.append(space); builder.append(str.charAt(i)); } else { builder.append(str.charAt(i)); } } courPos = builder.length(); textOnViewLength = builder.toString().length(); setText(builder.toString()); } }