输入时候动态的让银行卡格式化
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());
}
}