10

In my app, the user has to enter a phone number in an EditText field using the following format:

1(515)555-5555

I don't want the user to type "(", ")", or "-" while entering the number; I want these characters to be added automatically.

For example, suppose the user typed 1 -- the parenthesis after "1" should be added automatically, so that "1(" would be displayed. And I would like to have similar functionality while deleting.

I have tried to set text in the afterTextChanged method of onTextWatcher interface, but it is not working; instead it's causing an error. Any help will be greatly appreciated.

Donut
  • 110,061
  • 20
  • 134
  • 146
Amit Kumar
  • 123
  • 1
  • 1
  • 8
  • It would be really helpful to see your code for `afterTextChanged` and the log from the error. Without those, it's tough to know for sure what the problem is (though I'll take a guess anyway). – Mike Feb 23 '11 at 05:10

2 Answers2

11

you can try

editTextPhoneNumber.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

Check PhoneNumnerFormattingTextWatxher

in case you want your own implementation of TextWatcher then you can use folling appraoch:

import android.telephony.PhoneNumberFormattingTextWatcher;
import android.text.Editable;

/**
* Set this TextWatcher to EditText for Phone number
* formatting.
* 
* Along with this EditText should have
* 
* inputType= phone
* 
* maxLength=14    
*/
public class MyPhoneTextWatcher extends PhoneNumberFormattingTextWatcher {

private EditText editText;

/**
 * 
 * @param EditText
 *            to handle other events
 */
public MyPhoneTextWatcher(EditText editText) {
    // TODO Auto-generated constructor stub
    this.editText = editText;
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    // TODO Auto-generated method stub
    super.onTextChanged(s, start, before, count);

    //--- write your code here
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
    // TODO Auto-generated method stub
    super.beforeTextChanged(s, start, count, after);
}

@Override
public synchronized void afterTextChanged(Editable s) {
    // TODO Auto-generated method stub
    super.afterTextChanged(s);
}

}
Nayanesh Gupte
  • 2,735
  • 25
  • 37
10

You're probably running into a problem because afterTextChanged is re-entrant, i.e. changes made to the text cause the method to be called again.

If that's the problem, one way way around is to keep an instance variable flag:

public class MyTextWatcher implements TextWatcher {
    private boolean isInAfterTextChanged;

    public synchronized void afterTextChanged(Editable text) {
       if (!isInAfterTextChanged) {
           isInAfterTextChanged = true;

           // TODO format code goes here

           isInAfterTextChanged = false;
       }
    }
}

As an alternative, you could just use PhoneNumberFormattingTextWatcher -- it doesn't do the formatting that you described, but then again you don't have to do much to use it.

Mike
  • 2,422
  • 23
  • 14
  • thanks a lot mike ,after implementing ur suggestion its working fine. – Amit Kumar Mar 15 '11 at 14:15
  • This worked, but was tricky. For my formatting issue, I needed to make sure that the reformatting code ends with moving the cursor back (setSelection()), otherwise rewriting the text will result in the cursor always moved to the beginning (which is a frustrating interface.) – David Pisoni Apr 30 '13 at 16:38