我用以下方法解决了这个问题:
final EditText phoneNumber = (EditText) findViewById(R.id.phoneNumber);
phoneNumber.addTextChangedListener(new PhoneNumberTextWatcher());
phoneNumber.setFilters(new InputFilter[] { new PhoneNumberFilter(), new InputFilter.LengthFilter(12) });
PhoneNumberFilter - 确保电话号码匹配 XXX-XXX-XXXX:
public class PhoneNumberFilter extends NumberKeyListener {
@Override
public int getInputType() {
return InputType.TYPE_CLASS_PHONE;
}
@Override
protected char[] getAcceptedChars() {
return new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-' };
}
@Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
// Don't let phone numbers start with 1
if (dstart == 0 && source.equals("1"))
return "";
if (end > start) {
String destTxt = dest.toString();
String resultingTxt = destTxt.substring(0, dstart) + source.subSequence(start, end) + destTxt.substring(dend);
// Phone number must match xxx-xxx-xxxx
if (!resultingTxt.matches ("^\\d{1,1}(\\d{1,1}(\\d{1,1}(\\-(\\d{1,1}(\\d{1,1}(\\d{1,1}(\\-(\\d{1,1}(\\d{1,1}(\\d{1,1}(\\d{1,1}?)?)?)?)?)?)?)?)?)?)?)?")) {
return "";
}
}
return null;
}
}
PhoneNumberTextWatcher - 如果用户正在删除,则处理自动插入破折号和自动删除破折号:
public class PhoneNumberTextWatcher implements TextWatcher {
private boolean isFormatting;
private boolean deletingHyphen;
private int hyphenStart;
private boolean deletingBackward;
@Override
public void afterTextChanged(Editable text) {
if (isFormatting)
return;
isFormatting = true;
// If deleting hyphen, also delete character before or after it
if (deletingHyphen && hyphenStart > 0) {
if (deletingBackward) {
if (hyphenStart - 1 < text.length()) {
text.delete(hyphenStart - 1, hyphenStart);
}
} else if (hyphenStart < text.length()) {
text.delete(hyphenStart, hyphenStart + 1);
}
}
if (text.length() == 3 || text.length() == 7) {
text.append('-');
}
isFormatting = false;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (isFormatting)
return;
// Make sure user is deleting one char, without a selection
final int selStart = Selection.getSelectionStart(s);
final int selEnd = Selection.getSelectionEnd(s);
if (s.length() > 1 // Can delete another character
&& count == 1 // Deleting only one character
&& after == 0 // Deleting
&& s.charAt(start) == '-' // a hyphen
&& selStart == selEnd) { // no selection
deletingHyphen = true;
hyphenStart = start;
// Check if the user is deleting forward or backward
if (selStart == start + 1) {
deletingBackward = true;
} else {
deletingBackward = false;
}
} else {
deletingHyphen = false;
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}