類似銀行卡,電話号碼的EditText控件,可以自己設定分隔符和輸入的最大長度,代碼如下
package com.xxx.xxxxxx;
import android.content.Context;
import android.text.Editable;
import android.text.InputFilter;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;
/**
* 實作輸入框輸入内容插入分隔符
*
* @author yangjinbo
*
*/
public class DividerEditText extends EditText {
private String lastFormatString;
private char divideCharacter = ' ';
private int[] formatPattern = { 4 };
private int maxLength = 20;
private int[] divisionPattern;
public DividerEditText(Context context) {
super(context);
init();
}
public DividerEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DividerEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
// addTextChangedListener(mInputWatcher);
Divider u = new Divider();
addTextChangedListener(u);
setFilters(new InputFilter[] { u });
divisionPattern = getDivisionPatter();
}
/**
* 字元格式化模式,例如設定為{3,4,4},字元将要顯示成138 3800 3800的形式
*
* @param formatPattern
*/
public void setFormatPattern(int maxLength,int[] formatPattern) {
this.maxLength = maxLength;
this.formatPattern = formatPattern;
divisionPattern = getDivisionPatter();
}
public char getDividerCharacter() {
return divideCharacter;
}
public int getMaxLength() {
return maxLength;
}
public void setMaxLength(int maxLength) {
this.maxLength = maxLength;
}
/**
* 設定分隔字元
*
* @param dividerCharacter
*/
public void setDividerCharacter(char dividerCharacter) {
this.divideCharacter = dividerCharacter;
}
private CharSequence formatText(CharSequence str) {
int length = str.length();
int lastInsertPos = -1;
// 輸入的内容長度較少時,不顯示分隔符
if (length <= formatPattern[0] + 1) {
return deleteDivideChar(str);
}
CharSequence tmp = deleteDivideChar(str);
length = tmp.length();
StringBuilder builder = new StringBuilder();
for (int i = 0, j = 0; i < length; i++) {
builder.append(tmp.charAt(i));
if (i - formatPattern[j] - lastInsertPos == 0) {
lastInsertPos = i;
builder.append(divideCharacter);
if (j < formatPattern.length - 1) {
j++;
}
}
}
if (builder.charAt(builder.length() - 1) == divideCharacter) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
private CharSequence deleteDivideChar(CharSequence string) {
StringBuilder builder = new StringBuilder();
int length = string.length();
for (int i = 0; i < length; i++) {
if (string.charAt(i) != divideCharacter) {
builder.append(string.charAt(i));
}
}
return builder;
}
/**
* 擷取去掉分隔符的内容
*
* @return 去掉了分隔符的内容
*/
public String getRealInputText() {
return deleteDivideChar(getText()).toString();
}
private int[] getDivisionPatter() {
int len = 0;
int i = 0;
while (len < maxLength) {
if (i < formatPattern.length) {
len += formatPattern[i];
} else {
len += formatPattern[formatPattern.length - 1];
}
i++;
}
int[] arrayInt = new int[--i];
arrayInt[0] = formatPattern[0];
for (int j = 1; j < i; j++) {
arrayInt[j] = arrayInt[j - 1];
if (j < formatPattern.length) {
arrayInt[j] += formatPattern[j] + 1;
} else {
arrayInt[j] += formatPattern[formatPattern.length - 1] + 1;
}
}
return arrayInt;
}
final class Divider implements TextWatcher, InputFilter {
private int deleteDivider = 0;
public final void afterTextChanged(Editable source) {
if (this.deleteDivider > 1) {
int tmp = this.deleteDivider;
this.deleteDivider = 0;
source.delete(tmp - 1, tmp);
}
int j = 0;
for (int i = 0; i < source.length(); i++) {
char character = source.charAt(i);
if (i == divisionPattern[j]) {
if (j < divisionPattern.length - 1) {
j++;
}
if (character != divideCharacter) {
source.insert(i, String.valueOf(divideCharacter));
}
} else if (character == divideCharacter) {
source.delete(i, i + 1);
i--;
}
}
}
public final void beforeTextChanged(CharSequence paramCharSequence,
int paramInt1, int paramInt2, int paramInt3) {
}
public final void onTextChanged(CharSequence paramCharSequence,
int paramInt1, int paramInt2, int paramInt3) {
}
public final CharSequence filter(CharSequence source, int start,
int end, Spanned dest, int dstart, int dend) {
if (deleteDivideChar(
new SpannableStringBuilder(dest).replace(dstart, dend,
source, start, end).toString()).length() > maxLength)
return "";
SpannableStringBuilder result = new SpannableStringBuilder(source);
int[] arrayOfInt = divisionPattern;
int dLength = dend - dstart;
for (int i = 0; i < arrayOfInt.length; i++) {
if ((source.length() == 0) && (dstart == arrayOfInt[i])
&& (dest.charAt(dstart) == divideCharacter)) {
this.deleteDivider = arrayOfInt[i];
}
int j;
if ((dstart - dLength <= arrayOfInt[i])
&& (dstart + end - dLength >= arrayOfInt[i])
&& (((j = arrayOfInt[i] - dstart) == end) || ((j >= 0)
&& (j < end) && (result.charAt(j) != divideCharacter)))) {
result.insert(j, String.valueOf(divideCharacter));
end++;
}
}
return result;
}
}
}