Android - Formatting phone number in EditText - android

I need a little assistance making this to work, because server side API requires special format for phone number field. Maybe I could edit that field just before sending API request by replacing characters at specific positions, however that would still give the user freedom to insert wrong format for phone number. I need to make EditText assist him just right after he changed the text and direct him to right format.
For that I have used TextWatcher method afterTextChanged() and format which I need is next: (063)22-22-333
This is what I have tried:
private static final char space = '-';
private static final char brackets = '(';
private static final char brackets1 = ')';
etPhone.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) {
// (063)22-22-333
// -> Error
if (s.length() > 0 && !s.toString().startsWith("(")) {
s.replace(0, s.length(), "(0");
}
if (s.length() > 0 && s.length() == 8) {
final char c = s.charAt(s.length() - 1);
if (space == c) {
s.delete(s.length() - 1, s.length());
}
} else if (s.length() > 0 && s.length() == 5) {
final char c = s.charAt(s.length() - 1);
if (brackets1 == c) {
s.delete(s.length() - 1, s.length());
}
}
// Insert char where needed.
if (s.length() > 0 && s.length() == 8) {
char c = s.charAt(s.length() - 1);
// Only if its a digit where there should be a space we insert a space
if (Character.isDigit(c) && TextUtils.split(s.toString(), String.valueOf(space)).length <= 7) {
s.insert(s.length() - 1, String.valueOf(space));
}
} else if (s.length() > 0 && s.length() == 5) {
char c = s.charAt(s.length() - 1);
if (Character.isDigit(c) && TextUtils.split(s.toString(), String.valueOf(brackets1)).length <= 4) {
s.insert(s.length() - 1, String.valueOf(brackets1));
}
}
}
});
I'm getting an error after writing 4 character. Error is showing at the beginning.

You are using the split() method which needs as its 2nd parameter a regular expression and here is your problem: you need to escape "(" and ")" in regular expressions. So I made some changes:
private static final char space = '-';
private static final char brackets = '(';
private static final char brackets1 = ')';
private static final String sspace = "\\x32";
private static final String sbrackets = "\\x28";
private static final String sbrackets1 = "\\x29";
etPhone.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) {
// (063)22-22-333
// -> Error
if (s.length() > 0 && !s.toString().startsWith("(")) {
s.replace(0, s.length(), "(0");
}
if (s.length() > 0 && s.length() == 8) {
final char c = s.charAt(s.length() - 1);
if (space == c) {
s.delete(s.length() - 1, s.length());
}
} else if (s.length() > 0 && s.length() == 5) {
final char c = s.charAt(s.length() - 1);
if (brackets1 == c) {
s.delete(s.length() - 1, s.length());
}
}
// Insert char where needed.
if (s.length() > 0 && s.length() == 8) {
char c = s.charAt(s.length() - 1);
// Only if its a digit where there should be a space we insert a space
if (Character.isDigit(c) && TextUtils.split(s.toString(), sspace).length <= 7) {
s.insert(s.length() - 1, String.valueOf(space));
}
} else if (s.length() > 0 && s.length() == 5) {
char c = s.charAt(s.length() - 1);
if (Character.isDigit(c) && TextUtils.split(s.toString(), sbrackets1).length <= 4) {
s.insert(s.length() - 1, String.valueOf(brackets1));
}
}
}
});
Now you get no crash after the 3d char.
Every time you want to use split() instead of String.valueOf(brackets1) use brackets1 or sbrackets or sspace

You might have an easier time converting from a common format to the format that the server side is expecting. To get to a standard format, there are a couple of classes which already exist that might help you. Have you looked at PhoneNumberFormattingTextWatcher?
If you absolutely need to use your own watcher, there are other utils that can help you:
// this will result in the string "(212) 555-2232"
String number = PhoneNumberUtils.formatNumber("2125552232", "US")
After getting a predictable result, it should be trivial to convert to whatever your server needs.

Related

Android: Space after every 10 digit in edit text using text watcher

In android edit text, how to separate 10 digit number input by space? I am using android text watcher and I am trying to input multiple 10 digit numbers in the field. The issue arises when multiple numbers are copied and pasted in the field and that time, it doesn't take those spaces. Kindly let me know a solution in order to allow multiple number input with a space after every 10 digit number, when the number is copied from other place.
This will work for both type and copy/paste from other place.
yourEditText.addTextChangedListener(new TextWatcher() {
private static final char space = ' ';
#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) {
int pos = 0;
while (true) {
if (pos >= s.length()) break;
if (space == s.charAt(pos) && (((pos + 1) % 11) != 0 || pos + 1 == s.length())) {
s.delete(pos, pos + 1);
} else {
pos++;
}
}
pos = 10;
while (true) {
if (pos >= s.length()) break;
final char c = s.charAt(pos);
if (Character.isDigit(c)) {
s.insert(pos, "" + space);
}
pos += 11;
}
}
});
Edit and Use the following code as per your needs
StringBuilder s;
s = new StringBuilder(yourTxtView.getText().toString());
for(int i = 10; i < s.length(); i += 10){
s.insert(i, " "); // this line inserts a space
}
yourTxtView.setText(s.toString());
and when you need to get the String without spaces do this:
String str = yourTxtView.getText().toString().replace(" ", "");

Android - How to get edittext as in this xx-xxx-xxx-xxx-x format?

I want to show the number in this xx-xxx-xxx-xxx-x format on EditText.
Eg (01-140-176-515-4)
I tried modifying the below code which displays the number in credit card number format
(xxxx-xxxx-xxxx-xxxx)
et_cardnumber.addTextChangedListener(new TextWatcher() {
private static final int TOTAL_SYMBOLS = 19; // size of pattern 0000-0000-0000-0000
private static final int TOTAL_DIGITS = 16; // max numbers of digits in pattern: 0000 x 4
private static final int DIVIDER_MODULO = 5; // means divider position is every 5th symbol beginning with 1
private static final int DIVIDER_POSITION = DIVIDER_MODULO - 1; // means divider position is every 4th symbol beginning with 0
private static final char DIVIDER = '-';
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// noop
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
iv_cardtype.setImageResource(getCreditCardTypeForImageView(et_cardnumber.getText().toString()));
}
#Override
public void afterTextChanged(Editable s) {
if (!isInputCorrect(s, TOTAL_SYMBOLS, DIVIDER_MODULO, DIVIDER)) {
s.replace(0, s.length(), buildCorrecntString(getDigitArray(s, TOTAL_DIGITS), DIVIDER_POSITION, DIVIDER));
}
}
private boolean isInputCorrect(Editable s, int totalSymbols, int dividerModulo, char divider) {
boolean isCorrect = s.length() <= totalSymbols; // check size of entered string
for (int i = 0; i < s.length(); i++) { // chech that every element is right
if (i > 0 && (i + 1) % dividerModulo == 0) {
isCorrect &= divider == s.charAt(i);
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
private String buildCorrecntString(char[] digits, int dividerPosition, char divider) {
final StringBuilder formatted = new StringBuilder();
for (int i = 0; i < digits.length; i++) {
if (digits[i] != 0) {
formatted.append(digits[i]);
if ((i > 0) && (i < (digits.length - 1)) && (((i + 1) % dividerPosition) == 0)) {
formatted.append(divider);
}
}
}
return formatted.toString();
}
private char[] getDigitArray(final Editable s, final int size) {
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < s.length() && index < size; i++) {
char current = s.charAt(i);
if (Character.isDigit(current)) {
digits[index] = current;
index++;
}
}
return digits;
}
});
I couldn't get it right when i make changes to get the format which i want.
Can anyone help me to get the number in xx-xxx-xxx-xxx-x format?
i dont know much in Android , but try to build something like this .
str Yourstring = "";
for (int i = 0; i < digits.length; i++) {
if (i == 2 || i == 5 || i == 8 || i == 11) {
Yourstring = Yourstring + "-" +digits[i];
}
else
{
Yourstring = Yourstring +digits[i];
}
}
I answered this already in this link , please change the logic according to your format
Use this library.
it will allow according yo your formate
EditText Pattern lib

TextWatcher slow when using setText

I'm using TextWatcher to modify the EditText to always look like #tag1 #tag2...
Here is my code:
editHashtags.addTextChangedListener(new TextWatcher() {
private boolean lock = false;
private String toGo;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(before == 1) return;
toGo = s.toString();
if(toGo.charAt(0) != '#') {
toGo = '#' + toGo;
}
if(toGo.charAt(start) == ' ' && toGo.charAt(start - 1) == '#' && start > 0
|| toGo.charAt(start) == ' ' && toGo.charAt(start - 1) == ' ' && start > 0) {
toGo = toGo.substring(0, toGo.length() - 1);
} else if(toGo.charAt(start) == ' ') {
toGo += '#';
} else if(toGo.charAt(start) != '#' && toGo.charAt(start - 1) == ' ') {
toGo = toGo.substring(0, toGo.length() - 1) + '#' + toGo.charAt(start);
}
}
#Override
public void afterTextChanged(Editable s) {
if(lock) return;
toGo = toGo.replaceAll("#+", "#");
lock = true;
editHashtags.setText(toGo);
editHashtags.setSelection(toGo.length());
lock = false;
}
});
The problem is when I use lock to change the text. It appears that setText is really slow, so if I type fast, some characters are ignored.
What is the best approach to solve this issue?
Thank you.
The right way to modify a EditText using TextWatcher is modifying the mutable object Editable received on the afterTextChanged method.
You could also look at implementing a custom TransformationMethod instead, which might give you better performance. An implementation similar to the framework's ReplacementTransformationMethod, for instance.

Textwatcher - Different Last Char Situations

Long story short I am facing this problem: I am attaching a textwatcher to an edittext. As soon as "1" is the last char written on it, that should be replaced with the letter "a". But here is the problem: I'd like as soon as "a" is also the last char written on the edittext (user pressed "a"), EXCEPT THROUGH THE PREVIOUS METHOD, some things to be done. But as I test it and type "1", that is converted to "a" normally and the things I mention are also done. I can't seem to find a way to overpass this, can any suggestions be given? Thanks a lot. I use:
public void afterTextChanged(Editable s) {
//TODO Auto-generated method stub
if (s.length() > 0 && s.toString().charAt(s.length() - 1) == '1') {
current_string = s.toString().substring(0, (s.length() - 1));
et.setText(current_string + "a");
length = s.length();
et.setSelection(length);
}
else if (s.length() > 0 && s.toString().charAt(s.length() - 1) == 'a') {
//do some things
}
try this
public void afterTextChanged(Editable s) {
if (s.length() > 0 && s.toString().charAt(s.length() - 1) == 'a') {
//do some things
}
if (s.length() > 0 && s.toString().charAt(s.length() - 1) == '1') {
current_string = s.toString().substring(0, (s.length() - 1));
et.setText(current_string + "a");
length = s.length();
et.setSelection(length);
}
Do you mean.
1)when user enters the 1 in end it should replace by 'a'.
2)when user enters 'a' separately (not converted by the step 1) it should do something else
amount1.addTextChangedListener(new TextWatcher() {
int flagg;
public void onTextChanged(CharSequence s, int start, int before,
int count) {
System.out.println("flagg"+s+"#"+flagg );
if (s.length() > 0 && s.toString().charAt(s.length() - 1) == '1' )
{ System.out.println("Converting and doing NOthing");
flagg=1;
String current_string = s.toString().substring(0,(s.length() - 1));
amount1.setText(current_string + "a");
int length = s.length();
amount1.setSelection(length);
}
else if (s.length() > 0 && ( s.toString().charAt(s.length() - 1) == 'a') && flagg == 0 ) {
System.out.println("Staying same and doing Something");
amount2.setText(amount2.getText().toString() + "Z");
// do some things
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (start != 0) {
if ((s.toString()).substring(s.length() - 1).equals("a")) {
flagg = 1;
}
if ((s.toString()).substring(s.length() - 1).equals("1")) {
flagg = 0;
} else {
flagg = 0;
}
}
}
#Override
public void afterTextChanged(Editable arg0) {
}
});
//new flagg is set in if condition

Phone number formatting an EditText in Android

I am making a simple Address Book app (targeting 4.2) that takes name, address, city, state, zip and phone.
I want to format the phone number input as a phone number (XXX) XXX-XXXX, but I need to pull the value out as a string so I can store it in my database when I save. How can i do this??
I have the EditText set for "phone number" input but that obviously doesn't do too much.
Simply use the PhoneNumberFormattingTextWatcher, just call:
editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
Addition
To be clear, PhoneNumberFormattingTextWatcher's backbone is the PhoneNumberUtils class. The difference is the TextWatcher maintains the EditText while you must call PhoneNumberUtils.formatNumber() every time you change its contents.
There is a library called PhoneNumberUtils that can help you to cope with phone number conversions and comparisons. For instance, use ...
EditText text = (EditText) findViewById(R.id.editTextId);
PhoneNumberUtils.formatNumber(text.getText().toString())
... to format your number in a standard format.
PhoneNumberUtils.compare(String a, String b);
... helps with fuzzy comparisons. There are lots more. Check out http://developer.android.com/reference/android/telephony/PhoneNumberUtils.html for more.
p.s. setting the the EditText to phone is already a good choice; eventually it might be helpful to add digits e.g. in your layout it looks as ...
<EditText
android:id="#+id/editTextId"
android:inputType="phone"
android:digits="0123456789+"
/>
Simply Use This :
In Java Code :
editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
In XML Code :
<EditText
android:id="#+id/etPhoneNumber"
android:inputType="phone"/>
This code work for me. It'll auto format when text changed in edit text.
I've recently done a similar formatting like 1 (XXX) XXX-XXXX for Android EditText. Please find the code below. Just use the TextWatcher sub-class as the text changed listener :
....
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();
}
}
Maybe below sample project helps you;
https://github.com/reinaldoarrosi/MaskedEditText
That project contains a view class call MaskedEditText. As first, you should add it in your project.
Then you add below xml part in res/values/attrs.xml file of project;
<resources>
<declare-styleable name="MaskedEditText">
<attr name="mask" format="string" />
<attr name="placeholder" format="string" />
</declare-styleable>
</resources>
Then you will be ready to use MaskedEditText view.
As last, you should add MaskedEditText in your xml file what you want like below;
<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="_" >
Of course that, you can use it programmatically.
After those steps, adding MaskedEditText will appear like below;
As programmatically, if you want to take it's text value as unmasked, you may use below row;
maskedEditText.getText(true);
To take masked value, you may send false value instead of true value in the getText method.
You need to create a class:
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;
}
}
Use this as follows:
phone = view.findViewById(R.id.phone);
phone.addTextChangedListener(new PhoneTextFormatter(phone, "+7 (###) ###-####"));
If you're only interested in international numbers and you'd like to be able to show the flag of the country that matches the country code in the input, I wrote a small library for that:
https://github.com/tfcporciuncula/phonemoji
Here's how it looks:
Follow the instructions in this Answer to format the EditText mask.
https://stackoverflow.com/a/34907607/1013929
And after that, you can catch the original numbers from the masked string with:
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) {
}
}
More like clean:
#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;
}
}
You can use spawns to format phone numbers in Android. This solution is better than the others because it does not change input text. Formatting remains purely visual.
implementation 'com.googlecode.libphonenumber:libphonenumber:7.0.4'
Formatter class:
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
You can use a Regular Expression with pattern matching to extract number from a string.
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
Don't worry. I have make a most of better solution for you. You can see this simple app link below.
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) {
}
Not: Don't forget "implement TextWatcher" with your activity class.
Link :https://drive.google.com/open?id=0B-yo9VvU7jyBMjJpT29xc2k5bnc
Hope you are feeling cool for this solution.
You can accept only numbers and phone number type using java code
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
This code will avoid lot of validations after reading input
This code is work for me for (216) 555-5555
etphonenumber.addTextChangedListener(new TextWatcher()
{
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s)
{
String text = etphonenumber.getText().toString();
int textLength = etphonenumber.getText().length();
if (text.endsWith("-") || text.endsWith(" ") || text.endsWith(" "))
return;
if (textLength == 1) {
if (!text.contains("("))
{
etphonenumber.setText(new StringBuilder(text).insert(text.length() - 1, "(").toString());
etphonenumber.setSelection(etphonenumber.getText().length());
}
}
else if (textLength == 5)
{
if (!text.contains(")"))
{
etphonenumber.setText(new StringBuilder(text).insert(text.length() - 1, ")").toString());
etphonenumber.setSelection(etphonenumber.getText().length());
}
}
else if (textLength == 6)
{
etphonenumber.setText(new StringBuilder(text).insert(text.length() - 1, " ").toString());
etphonenumber.setSelection(etphonenumber.getText().length());
}
else if (textLength == 10)
{
if (!text.contains("-"))
{
etphonenumber.setText(new StringBuilder(text).insert(text.length() - 1, "-").toString());
etphonenumber.setSelection(etphonenumber.getText().length());
}
}
}
});

Categories

Resources