Phone android 中的数字自动格式化
Phone number auto formatting in android
我需要按照此格式 (222) 222-2222 ext222222
在 android 的编辑文本中格式化 phone 数字
我创建了一个为我自动格式化的观察者。观察者工作正常并正确格式化 phone 数字。我唯一的问题是,当有人手动转到输入的 phone 中的某个其他位置并开始删除或添加数字时,自动格式化不起作用。
关于如何解决这个问题的任何想法。
这是我当前的观察者的样子:
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(s: Editable) {
val text = editText.text.toString()
val textLength = editText.text.length
if (text.endsWith("-") || text.endsWith(" ")) {
return
}
if (textLength == 1) {
if (!text.contains("(")) {
editText.setText(StringBuilder(text).insert(text.length - 1, "(").toString())
editText.setSelection(editText.text.length)
}
} else if (textLength == 5) {
if (!text.contains(")")) {
editText.setText(StringBuilder(text).insert(text.length - 1, ")").toString())
editText.setSelection(editText.text.length)
}
} else if (textLength == 6) {
editText.setText(StringBuilder(text).insert(text.length - 1, " ").toString())
editText.setSelection(editText.text.length)
} else if (textLength == 10) {
if (!text.contains("-")) {
editText.setText(StringBuilder(text).insert(text.length - 1, "-").toString())
editText.setSelection(editText.text.length)
}
} else if (textLength == 15) {
if (text.contains("-")) {
editText.setText(StringBuilder(text).insert(text.length - 1, " ext").toString())
editText.setSelection(editText.text.length)
}
}
}
})
您应该删除观察器以避免多次触发 afterTextChanged
并在设置方法文本后立即恢复它。
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(editable: Editable) {
val text = editText.text.toString()
val textLength = editText.text.length
if (text.endsWith("-") || text.endsWith(" ")) {
return
}
if (textLength == 1) {
if (!text.contains("(")) {
setText(StringBuilder(text).insert(text.length - 1, "(").toString())
}
} else if (textLength == 5) {
if (!text.contains(")")) {
setText(StringBuilder(text).insert(text.length - 1, ")").toString())
}
} else if (textLength == 6) {
setText(StringBuilder(text).insert(text.length - 1, " ").toString())
} else if (textLength == 10) {
if (!text.contains("-")) {
setText(StringBuilder(text).insert(text.length - 1, "-").toString())
}
} else if (textLength == 15) {
if (text.contains("-")) {
setText(StringBuilder(text).insert(text.length - 1, " ext").toString())
}
}
}
private fun setText(text: String){
editText.removeTextChangedListener(this)
editText.editableText.replace(0, editText.text.length, text)
editText.setSelection(text.length)
editText.addTextChangedListener(this)
}
})
经过这些更改后,它工作正常,但在 ext
部分崩溃(与您的问题无关)。或者,您可以使用 libphonenumber AsYouType 功能来节省一些工作
如果一切都取决于我,这就是我可以处理的方式(见行间评论)。这仅适用于 phone 号码格式,假设它是最多 10 位数字的区域号码:
phoneNumber.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
/* Let me prepare a StringBuilder to hold all digits of the edit text */
StringBuilder digits = new StringBuilder();
/* this is the phone StringBuilder that will hold the phone number */
StringBuilder phone = new StringBuilder();
/* let's take all characters from the edit text */
char[] chars = phoneNumber.getText().toString().toCharArray();
/* a loop to extract all digits */
for (int x = 0; x < chars.length; x++) {
if (Character.isDigit(chars[x])) {
/* if its a digit append to digits string builder */
digits.append(chars[x]);
}
}
if (digits.toString().length() >=3) {
/* our phone formatting starts at the third character and starts with the country code*/
String countryCode = new String();
/* we build the country code */
countryCode += "(" + digits.toString().substring(0, 3) + ") ";
/** and we append it to phone string builder **/
phone.append(countryCode);
/** if digits are more than or just 6, that means we already have our state code/region code **/
if (digits.toString().length()>=6)
{
String regionCode=new String();
/** we build the state/region code **/
regionCode+=digits.toString().substring(3,6)+"-";
/** we append the region code to phone **/
phone.append(regionCode);
/** the phone number will not go over 12 digits if ten, set the limit to ten digits**/
if (digits.toString().length()>=10)
{
phone.append(digits.toString().substring(6,10));
}else
{
phone.append(digits.toString().substring(6));
}
}else
{
phone.append(digits.toString().substring(3));
}
/** remove the watcher so you can not capture the affectation you are going to make, to avoid infinite loop on text change **/
phoneNumber.removeTextChangedListener(this);
/** set the new text to the EditText **/
phoneNumber.setText(phone.toString());
/** bring the cursor to the end of input **/
phoneNumber.setSelection(phoneNumber.getText().toString().length());
/* bring back the watcher and go on listening to change events */
phoneNumber.addTextChangedListener(this);
} else {
return;
}
}
});
每次用户更改 EditText 的值时,此代码都会重新格式化 phone 数字。我已经亲自测试过它并且它可以工作并且不会崩溃。你可以测试一下。
编辑: 这是一个 java 代码,但我认为您可以轻松地将其重写为 Kotlin。
我需要按照此格式 (222) 222-2222 ext222222
在 android 的编辑文本中格式化 phone 数字
我创建了一个为我自动格式化的观察者。观察者工作正常并正确格式化 phone 数字。我唯一的问题是,当有人手动转到输入的 phone 中的某个其他位置并开始删除或添加数字时,自动格式化不起作用。
关于如何解决这个问题的任何想法。
这是我当前的观察者的样子:
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(s: Editable) {
val text = editText.text.toString()
val textLength = editText.text.length
if (text.endsWith("-") || text.endsWith(" ")) {
return
}
if (textLength == 1) {
if (!text.contains("(")) {
editText.setText(StringBuilder(text).insert(text.length - 1, "(").toString())
editText.setSelection(editText.text.length)
}
} else if (textLength == 5) {
if (!text.contains(")")) {
editText.setText(StringBuilder(text).insert(text.length - 1, ")").toString())
editText.setSelection(editText.text.length)
}
} else if (textLength == 6) {
editText.setText(StringBuilder(text).insert(text.length - 1, " ").toString())
editText.setSelection(editText.text.length)
} else if (textLength == 10) {
if (!text.contains("-")) {
editText.setText(StringBuilder(text).insert(text.length - 1, "-").toString())
editText.setSelection(editText.text.length)
}
} else if (textLength == 15) {
if (text.contains("-")) {
editText.setText(StringBuilder(text).insert(text.length - 1, " ext").toString())
editText.setSelection(editText.text.length)
}
}
}
})
您应该删除观察器以避免多次触发 afterTextChanged
并在设置方法文本后立即恢复它。
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(editable: Editable) {
val text = editText.text.toString()
val textLength = editText.text.length
if (text.endsWith("-") || text.endsWith(" ")) {
return
}
if (textLength == 1) {
if (!text.contains("(")) {
setText(StringBuilder(text).insert(text.length - 1, "(").toString())
}
} else if (textLength == 5) {
if (!text.contains(")")) {
setText(StringBuilder(text).insert(text.length - 1, ")").toString())
}
} else if (textLength == 6) {
setText(StringBuilder(text).insert(text.length - 1, " ").toString())
} else if (textLength == 10) {
if (!text.contains("-")) {
setText(StringBuilder(text).insert(text.length - 1, "-").toString())
}
} else if (textLength == 15) {
if (text.contains("-")) {
setText(StringBuilder(text).insert(text.length - 1, " ext").toString())
}
}
}
private fun setText(text: String){
editText.removeTextChangedListener(this)
editText.editableText.replace(0, editText.text.length, text)
editText.setSelection(text.length)
editText.addTextChangedListener(this)
}
})
经过这些更改后,它工作正常,但在 ext
部分崩溃(与您的问题无关)。或者,您可以使用 libphonenumber AsYouType 功能来节省一些工作
如果一切都取决于我,这就是我可以处理的方式(见行间评论)。这仅适用于 phone 号码格式,假设它是最多 10 位数字的区域号码:
phoneNumber.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
/* Let me prepare a StringBuilder to hold all digits of the edit text */
StringBuilder digits = new StringBuilder();
/* this is the phone StringBuilder that will hold the phone number */
StringBuilder phone = new StringBuilder();
/* let's take all characters from the edit text */
char[] chars = phoneNumber.getText().toString().toCharArray();
/* a loop to extract all digits */
for (int x = 0; x < chars.length; x++) {
if (Character.isDigit(chars[x])) {
/* if its a digit append to digits string builder */
digits.append(chars[x]);
}
}
if (digits.toString().length() >=3) {
/* our phone formatting starts at the third character and starts with the country code*/
String countryCode = new String();
/* we build the country code */
countryCode += "(" + digits.toString().substring(0, 3) + ") ";
/** and we append it to phone string builder **/
phone.append(countryCode);
/** if digits are more than or just 6, that means we already have our state code/region code **/
if (digits.toString().length()>=6)
{
String regionCode=new String();
/** we build the state/region code **/
regionCode+=digits.toString().substring(3,6)+"-";
/** we append the region code to phone **/
phone.append(regionCode);
/** the phone number will not go over 12 digits if ten, set the limit to ten digits**/
if (digits.toString().length()>=10)
{
phone.append(digits.toString().substring(6,10));
}else
{
phone.append(digits.toString().substring(6));
}
}else
{
phone.append(digits.toString().substring(3));
}
/** remove the watcher so you can not capture the affectation you are going to make, to avoid infinite loop on text change **/
phoneNumber.removeTextChangedListener(this);
/** set the new text to the EditText **/
phoneNumber.setText(phone.toString());
/** bring the cursor to the end of input **/
phoneNumber.setSelection(phoneNumber.getText().toString().length());
/* bring back the watcher and go on listening to change events */
phoneNumber.addTextChangedListener(this);
} else {
return;
}
}
});
每次用户更改 EditText 的值时,此代码都会重新格式化 phone 数字。我已经亲自测试过它并且它可以工作并且不会崩溃。你可以测试一下。
编辑: 这是一个 java 代码,但我认为您可以轻松地将其重写为 Kotlin。