Android에서 EditText 서식을 지정하는 전화 번호
이름, 주소, 도시, 주, 우편 번호 및 전화 번호를 사용하는 간단한 주소록 앱 (4.2 타겟팅)을 만들고 있습니다.
입력 한 전화 번호를 전화 번호 (XXX) XXX-XXXX 형식으로 지정하고 싶지만 저장할 때 데이터베이스에 저장할 수 있도록 값을 문자열로 가져와야합니다. 어떻게 할 수 있습니까 ?? "전화 번호"입력에 대해 EditText를 설정했지만 분명히 너무 많은 작업을 수행하지는 않습니다.
전화 번호 변환 및 비교에 대처하는 데 도움이되는 PhoneNumberUtils 라는 라이브러리 가 있습니다. 예를 들어 ...를 사용하십시오.
EditText text = (EditText) findViewById(R.id.editTextId);
PhoneNumberUtils.formatNumber(text.getText().toString())
... 표준 형식으로 번호 형식을 지정합니다.
PhoneNumberUtils.compare(String a, String b);
... 퍼지 비교에 도움이됩니다. 더 많이 있습니다. 자세한 내용은 http://developer.android.com/reference/android/telephony/PhoneNumberUtils.html 을 확인하세요 .
ps EditText를로 설정하는 phone
것은 이미 좋은 선택입니다. 결국 digits
레이아웃 에 추가하는 것이 도움이 될 수 있습니다 .
<EditText
android:id="@+id/editTextId"
android:inputType="phone"
android:digits="0123456789+"
/>
PhoneNumberFormattingTextWatcher를 사용하고 다음을 호출하십시오.
editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
추가
명확하게 말하면 PhoneNumberFormattingTextWatcher의 백본 은 PhoneNumberUtils 클래스입니다. 차이점은 TextWatcher는 EditText를 유지 PhoneNumberUtils.formatNumber()
하지만 내용을 변경할 때마다 호출해야한다는 것 입니다.
이것을 사용하십시오 :
자바 코드에서 :
editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
XML 코드에서 :
<EditText
android:id="@+id/etPhoneNumber"
android:inputType="phone"/>
이 코드는 저에게 효과적입니다. 편집 텍스트에서 텍스트가 변경되면 자동 서식이 적용됩니다.
최근 Android EditText에 대해 1 (XXX) XXX-XXXX와 같은 유사한 형식을 지정했습니다. 아래 코드를 찾으십시오. TextWatcher 하위 클래스를 텍스트 변경 리스너로 사용하십시오. ....
UsPhoneNumberFormatter addLineNumberFormatter = new UsPhoneNumberFormatter(
new WeakReference<EditText>(mYourEditText));
mYourEditText.addTextChangedListener(addLineNumberFormatter);
...
private class UsPhoneNumberFormatter implements TextWatcher {
//This TextWatcher sub-class formats entered numbers as 1 (123) 456-7890
private boolean mFormatting; // this is a flag which prevents the
// stack(onTextChanged)
private boolean clearFlag;
private int mLastStartLocation;
private String mLastBeforeText;
private WeakReference<EditText> mWeakEditText;
public UsPhoneNumberFormatter(WeakReference<EditText> weakEditText) {
this.mWeakEditText = weakEditText;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (after == 0 && s.toString().equals("1 ")) {
clearFlag = true;
}
mLastStartLocation = start;
mLastBeforeText = s.toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO: Do nothing
}
@Override
public void afterTextChanged(Editable s) {
// Make sure to ignore calls to afterTextChanged caused by the work
// done below
if (!mFormatting) {
mFormatting = true;
int curPos = mLastStartLocation;
String beforeValue = mLastBeforeText;
String currentValue = s.toString();
String formattedValue = formatUsNumber(s);
if (currentValue.length() > beforeValue.length()) {
int setCusorPos = formattedValue.length()
- (beforeValue.length() - curPos);
mWeakEditText.get().setSelection(setCusorPos < 0 ? 0 : setCusorPos);
} else {
int setCusorPos = formattedValue.length()
- (currentValue.length() - curPos);
if(setCusorPos > 0 && !Character.isDigit(formattedValue.charAt(setCusorPos -1))){
setCusorPos--;
}
mWeakEditText.get().setSelection(setCusorPos < 0 ? 0 : setCusorPos);
}
mFormatting = false;
}
}
private String formatUsNumber(Editable text) {
StringBuilder formattedString = new StringBuilder();
// Remove everything except digits
int p = 0;
while (p < text.length()) {
char ch = text.charAt(p);
if (!Character.isDigit(ch)) {
text.delete(p, p + 1);
} else {
p++;
}
}
// Now only digits are remaining
String allDigitString = text.toString();
int totalDigitCount = allDigitString.length();
if (totalDigitCount == 0
|| (totalDigitCount > 10 && !allDigitString.startsWith("1"))
|| totalDigitCount > 11) {
// May be the total length of input length is greater than the
// expected value so we'll remove all formatting
text.clear();
text.append(allDigitString);
return allDigitString;
}
int alreadyPlacedDigitCount = 0;
// Only '1' is remaining and user pressed backspace and so we clear
// the edit text.
if (allDigitString.equals("1") && clearFlag) {
text.clear();
clearFlag = false;
return "";
}
if (allDigitString.startsWith("1")) {
formattedString.append("1 ");
alreadyPlacedDigitCount++;
}
// The first 3 numbers beyond '1' must be enclosed in brackets "()"
if (totalDigitCount - alreadyPlacedDigitCount > 3) {
formattedString.append("("
+ allDigitString.substring(alreadyPlacedDigitCount,
alreadyPlacedDigitCount + 3) + ") ");
alreadyPlacedDigitCount += 3;
}
// There must be a '-' inserted after the next 3 numbers
if (totalDigitCount - alreadyPlacedDigitCount > 3) {
formattedString.append(allDigitString.substring(
alreadyPlacedDigitCount, alreadyPlacedDigitCount + 3)
+ "-");
alreadyPlacedDigitCount += 3;
}
// All the required formatting is done so we'll just copy the
// remaining digits.
if (totalDigitCount > alreadyPlacedDigitCount) {
formattedString.append(allDigitString
.substring(alreadyPlacedDigitCount));
}
text.clear();
text.append(formattedString.toString());
return formattedString.toString();
}
}
아마도 아래 샘플 프로젝트가 도움이 될 것입니다.
https://github.com/reinaldoarrosi/MaskedEditText
해당 프로젝트에는 뷰 클래스 호출이 포함되어 있습니다 MaskedEditText
. 먼저 프로젝트에 추가해야합니다 .
그런 다음 프로젝트의 res / values / attrs.xml 파일에 아래 xml 부분을 추가합니다.
<resources>
<declare-styleable name="MaskedEditText">
<attr name="mask" format="string" />
<attr name="placeholder" format="string" />
</declare-styleable>
</resources>
그러면 MaskedEditText
보기 를 사용할 준비가 된 것 입니다.
마지막으로 아래와 같이 xml 파일에 MaskedEditText를 추가해야합니다.
<packagename.currentfolder.MaskedEditText
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/maskedEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:text="5"
app:mask="(999) 999-9999"
app:placeholder="_" >
물론 프로그래밍 방식으로 사용할 수 있습니다.
이 단계 후에 추가 MaskedEditText
는 다음과 같이 나타납니다.
프로그래밍 방식으로 텍스트 값을 마스크되지 않은 상태로 사용하려면 아래 행을 사용할 수 있습니다.
maskedEditText.getText(true);
마스킹 된 값을 사용하려면 메서드 에서 false
값 대신 true
값을 보낼 수 있습니다 getText
.
이 답변의 지침에 따라 EditText 마스크의 형식을 지정하십시오.
그 후 다음을 사용하여 마스킹 된 문자열에서 원래 숫자를 잡을 수 있습니다.
String phoneNumbers = maskedString.replaceAll("[^\\d]", "");
//(123) 456 7890 formate set
private int textlength = 0;
public class MyPhoneTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
String text = etMobile.getText().toString();
textlength = etMobile.getText().length();
if (text.endsWith(" "))
return;
if (textlength == 1) {
if (!text.contains("(")) {
etMobile.setText(new StringBuilder(text).insert(text.length() - 1, "(").toString());
etMobile.setSelection(etMobile.getText().length());
}
} else if (textlength == 5) {
if (!text.contains(")")) {
etMobile.setText(new StringBuilder(text).insert(text.length() - 1, ")").toString());
etMobile.setSelection(etMobile.getText().length());
}
} else if (textlength == 6 || textlength == 10) {
etMobile.setText(new StringBuilder(text).insert(text.length() - 1, " ").toString());
etMobile.setSelection(etMobile.getText().length());
}
}
@Override
public void afterTextChanged(Editable editable) {
}
}
패턴 일치와 함께 정규식을 사용하여 문자열에서 숫자를 추출 할 수 있습니다.
String s="";
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("(1111)123-456-789"); //editText.getText().toString()
while (m.find()) {
s=s+m.group(0);
}
System.out.println("............"+s);
Output : ............1111123456789
더 깨끗하게 :
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text = etyEditText.getText();
int textlength = etyEditText.getText().length();
if (text.endsWith("(") ||text.endsWith(")")|| text.endsWith(" ") || text.endsWith("-") )
return;
switch (textlength){
case 1:
etyEditText.setEditText(new StringBuilder(text).insert(text.length() - 1, "(").toString());
etyEditText.setSelection(etyEditText.getText().length());
break;
case 5:
etyEditText.setEditText(new StringBuilder(text).insert(text.length() - 1, ")").toString());
etyEditText.setSelection(etyEditText.getText().length());
break;
case 6:
etyEditText.setEditText(new StringBuilder(text).insert(text.length() - 1, " ").toString());
etyEditText.setSelection(etyEditText.getText().length());
break;
case 10:
etyEditText.setEditText(new StringBuilder(text).insert(text.length() - 1, "-").toString());
etyEditText.setSelection(etyEditText.getText().length());
break;
}
}
걱정하지 마세요. 나는 당신을 위해 더 나은 솔루션을 최대한 활용했습니다. 이 간단한 앱 링크는 아래에서 볼 수 있습니다.
private EditText mPasswordField;
public int textLength = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPasswordField = (EditText) findViewById(R.id.password_field);
mPasswordField.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text = mPasswordField.getText().toString();
textLength = mPasswordField.getText().length();
if (text.endsWith("-") || text.endsWith(" ") || text.endsWith(" "))
return;
if (textLength == 1) {
if (!text.contains("(")) {
mPasswordField.setText(new StringBuilder(text).insert(text.length() - 1, "(").toString());
mPasswordField.setSelection(mPasswordField.getText().length());
}
} else if (textLength == 5) {
if (!text.contains(")")) {
mPasswordField.setText(new StringBuilder(text).insert(text.length() - 1, ")").toString());
mPasswordField.setSelection(mPasswordField.getText().length());
}
} else if (textLength == 6) {
mPasswordField.setText(new StringBuilder(text).insert(text.length() - 1, " ").toString());
mPasswordField.setSelection(mPasswordField.getText().length());
} else if (textLength == 10) {
if (!text.contains("-")) {
mPasswordField.setText(new StringBuilder(text).insert(text.length() - 1, "-").toString());
mPasswordField.setSelection(mPasswordField.getText().length());
}
} else if (textLength == 15) {
if (text.contains("-")) {
mPasswordField.setText(new StringBuilder(text).insert(text.length() - 1, "-").toString());
mPasswordField.setSelection(mPasswordField.getText().length());
}
}else if (textLength == 18) {
if (text.contains("-")) {
mPasswordField.setText(new StringBuilder(text).insert(text.length() - 1, "-").toString());
mPasswordField.setSelection(mPasswordField.getText().length());
}
} else if (textLength == 20) {
Intent i = new Intent(MainActivity.this, Activity2.class);
startActivity(i);
}
}
@Override
public void afterTextChanged(Editable s) {
}
참고 : 활동 클래스와 함께 "TextWatcher 구현"을 잊지 마십시오.
링크 : https://drive.google.com/open?id=0B-yo9VvU7jyBMjJpT29xc2k5bnc
이 솔루션에 대해 기분이 좋기를 바랍니다.
수업을 만들어야합니다.
public class PhoneTextFormatter implements TextWatcher {
private final String TAG = this.getClass().getSimpleName();
private EditText mEditText;
private String mPattern;
public PhoneTextFormatter(EditText editText, String pattern) {
mEditText = editText;
mPattern = pattern;
//set max length of string
int maxLength = pattern.length();
mEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength)});
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
StringBuilder phone = new StringBuilder(s);
Log.d(TAG, "join");
if (count > 0 && !isValid(phone.toString())) {
for (int i = 0; i < phone.length(); i++) {
Log.d(TAG, String.format("%s", phone));
char c = mPattern.charAt(i);
if ((c != '#') && (c != phone.charAt(i))) {
phone.insert(i, c);
}
}
mEditText.setText(phone);
mEditText.setSelection(mEditText.getText().length());
}
}
@Override
public void afterTextChanged(Editable s) {
}
private boolean isValid(String phone)
{
for (int i = 0; i < phone.length(); i++) {
char c = mPattern.charAt(i);
if (c == '#') continue;
if (c != phone.charAt(i)) {
return false;
}
}
return true;
}
}
다음과 같이 사용하십시오.
phone = view.findViewById(R.id.phone);
phone.addTextChangedListener(new PhoneTextFormatter(phone, "+7 (###) ###-####"));
Java 코드를 사용하여 숫자와 전화 번호 유형 만 허용 할 수 있습니다.
EditText number1 = (EditText) layout.findViewById(R.id.edittext);
number1.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_CLASS_PHONE);
number1.setKeyListener(DigitsKeyListener.getInstance("0123456789”));
number1.setFilters(new InputFilter[] {new InputFilter.LengthFilter(14)}); // 14 is max digits
이 코드는 입력을 읽은 후 많은 유효성 검사를 방지합니다.
스폰을 사용하여 Android에서 전화 번호 형식을 지정할 수 있습니다. 이 솔루션은 입력 텍스트를 변경하지 않기 때문에 다른 솔루션보다 낫습니다. 서식은 순전히 시각적으로 유지됩니다.
implementation 'com.googlecode.libphonenumber:libphonenumber:7.0.4'
포맷터 클래스 :
open class PhoneNumberFormatter : TransformationMethod {
private val mFormatter: AsYouTypeFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(Locale.getDefault().country)
override fun getTransformation(source: CharSequence, view: View): CharSequence {
val formatted = format(source)
if (source is Spannable) {
setSpans(source, formatted)
return source
}
return formatted
}
override fun onFocusChanged(view: View?, sourceText: CharSequence?, focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) = Unit
private fun setSpans(spannable: Spannable, formatted: CharSequence): CharSequence {
spannable.clearSpawns()
var charterIndex = 0
var formattedIndex = 0
var spawn = ""
val spawns: List<String> = spannable
.map {
spawn = ""
charterIndex = formatted.indexOf(it, formattedIndex)
if (charterIndex != -1){
spawn = formatted.substring(formattedIndex, charterIndex-1)
formattedIndex = charterIndex+1
}
spawn
}
spawns.forEachIndexed { index, sequence ->
spannable.setSpan(CharterSpan(sequence), index, index + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
return formatted
}
private fun Spannable.clearSpawns() =
this
.getSpans(0, this.length, CharterSpan::class.java)
.forEach { this.removeSpan(it) }
private fun format(spannable: CharSequence): String {
mFormatter.clear()
var formated = ""
for (i in 0 until spannable.length) {
formated = mFormatter.inputDigit(spannable[i])
}
return formated
}
private inner class CharterSpan(private val charters: String) : ReplacementSpan() {
var space = 0
override fun getSize(paint: Paint, text: CharSequence, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
space = Math.round(paint.measureText(charters, 0, charters.length))
return Math.round(paint.measureText(text, start, end)) + space
}
override fun draw(canvas: Canvas, text: CharSequence, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
space = Math.round(paint.measureText(charters, 0, charters.length))
canvas.drawText(text, start, end, x + space, y.toFloat(), paint)
canvas.drawText(charters, x, y.toFloat(), paint)
}
}
}
Uasge :
editText.transformationMethod = formatter
TelephonyManager manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String CountryID= manager.getSimCountryIso().toUpperCase();
try{
PhoneNumberUtil pnu = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber pn1 = pnu.parse("99", CountryID);
String pnE1641 = pnu.format(pn1, PhoneNumberUtil.PhoneNumberFormat.E164);
code = pnE1641.substring(0, pnE1641.length()-2);
codeLength = code.length();
Log.e("dfdsfdsfsdfsdf", "onCreate: "+codeLength);
}catch (Exception e){
Log.e("dfdsfdsfsdfsdf", "onCreate: "+e);
}
phoneEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
int digits = phoneEditText.getText().toString().length();
if (digits > 1)
lastChar = phoneEditText.getText().toString().substring(digits-1);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
int digits = phoneEditText.getText().toString().length();
Log.d("LENGTH",""+digits);
if (!lastChar.equals("-")) {
if (digits == codeLength+6) {
phoneEditText.append("-");
}
}
}
@Override
public void afterTextChanged(Editable s) {
if (!s.toString().startsWith("("+code+") ")) {
phoneEditText.setText("("+code+") ");
Selection.setSelection(phoneEditText.getText(), phoneEditText.getText().length());
}
}
});
참조 URL : https://stackoverflow.com/questions/15647327/phone-number-formatting-an-edittext-in-android
'development' 카테고리의 다른 글
레이크 인 유닛 및 기능 테스트의 시드 값 사용 (0) | 2020.12.28 |
---|---|
C # : 시스템 색상을 기반으로 더 밝은 / 어두운 색상 만들기 (0) | 2020.12.27 |
Android Studio- 모듈 없음 (0) | 2020.12.27 |
Node.js Port 3000이 이미 사용 중이지만 실제로는 그렇지 않습니까? (0) | 2020.12.27 |
태그 버튼 (0) | 2020.12.27 |