16 Comments

  1. Namor Alves

    Olá, estou gostando deste tutorial só que está faltando uma parte:

    Com a mascara pronta agora é só fazer a troca dos seus EditText no XML do layout veja como fica:

    Como deve chamar no XML/Activity?

  2. Valmir

    Namor,

    Descobri como fazer a substituição citada pelo autor.
    Por favor, leia o exemplo a seguir:

    <EditText
    android:id="@+id/editNumero"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"

    <br.com.mobprime.mask.PhoneEditText
    android:id="@+id/editNumero"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"

    No XML altere o nome da tag pelo nome completo da classe.
    Para mim funcionou.
    []s.

  3. Bruno Ramos Dias

    Excelente abordagem criar a própria implementação do EditText, muito sagaz e u uso a filosofia clean code. e deixou o código desacoplado podendo ser re-utilizado em vários locais do projeto

  4. Roberto

    Olá, gostei muito desse tutorial. Só que ao digitar ou apagar um valor o texto é realocado e o cursor vai para o final. Fiz algumas modificações que me ajudaram.
    As modificações foram no addTextChangedListener…

    Na classe deve se declarar int tamanhoAntes = 0;

    this.addTextChangedListener(new TextWatcher() {
    public void afterTextChanged(Editable s) {

    String atual = s.toString();
    if (isAtualizando) {
    isAtualizando = false;
    return;
    }
    String numero = atual.replaceAll(“[^0-9]*”, “”);
    if (numero.length() > 10)
    numero = numero.substring(0, 10);
    int tamanho = numero.length();

    if (tamanhoAntes > tamanho) {
    isAtualizando = true;
    int cursor = PhoneEditText.this.getSelectionStart();
    if (cursor == 5)
    cursor = 3;
    PhoneEditText.this.setText(s.toString());
    PhoneEditText.this.setSelection(cursor);
    return;
    }

    String padding = fazPadding(numero, tamanhoMaximoNumeros);
    String ddd = padding.substring(0, 2);
    String parte1 = padding.substring(2, 6);
    String parte2 = padding.substring(6, 10);
    String phone = “(” + ddd + “) ” + parte1 + “-” + parte2;
    isAtualizando = true;
    int cursor = PhoneEditText.this.getSelectionStart();
    PhoneEditText.this.setText(phone);
    if (cursor == 1 || cursor == 10)
    cursor++;
    if (cursor == 4) {
    cursor += 2;
    }
    if (cursor > 14)
    cursor = 14;
    PhoneEditText.this.setSelection(cursor);
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    tamanhoAntes = s.toString().replaceAll(“[^0-9]*”, “”).length();
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }
    });

    Repare que o vetor positioning pode ser apagado com essa implementação.

    Abraços!!

  5. Copiei o teu código e montei uma máscara de CEP, mas não sei porque, quando estou apagando os caracteres, ele pára no hífen ( – ) e não apaga.

    package com.lstractor.prospect;

    import android.content.Context;
    import android.text.Editable;
    import android.text.InputType;
    import android.text.TextWatcher;
    import android.text.method.NumberKeyListener;
    import android.util.AttributeSet;
    import android.widget.EditText;

    public class CepEditText extends EditText {
    private boolean isUpdating;

    /*
    * Maps the cursor position from phone number to masked number… 1234567890
    * => 12345-678
    */
    private int positioning[] = { 0, 1, 2, 3, 4, 6, 7, 8, 9 };

    public CepEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initialize();

    }

    public CepEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();

    }

    public CepEditText(Context context) {
    super(context);
    initialize();

    }

    public String getCleanText() {
    String text = CepEditText.this.getText().toString();

    text.replaceAll(“[^0-9]*”, “”);
    return text;

    }

    private void initialize() {

    final int maxNumberLength = 8;
    this.setKeyListener(keylistenerNumber);

    this.setText(” – “);
    this.setSelection(1);

    this.addTextChangedListener(new TextWatcher() {
    public void afterTextChanged(Editable s) {
    String current = s.toString();

    /*
    * Ok, here is the trick… calling setText below will recurse
    * to this function, so we set a flag that we are actually
    * updating the text, so we don’t need to reprocess it…
    */
    if (isUpdating) {
    isUpdating = false;
    return;

    }

    /* Strip any non numeric digit from the String… */
    String number = current.replaceAll(“[^0-9]*”, “”);
    if (number.length() > 8)
    {
    number = number.substring(0, 8);
    }
    int length = number.length();

    /* Pad the number to 10 characters… */
    String paddedNumber = padNumber(number, maxNumberLength);

    /* Split phone number into parts… */
    String part1 = paddedNumber.substring(0, 5);
    String part2 = paddedNumber.substring(5, 8);

    /* build the masked phone number… */
    String cep = part1 + “-” + part2;

    /*
    * Set the update flag, so the recurring call to
    * afterTextChanged won’t do nothing…
    */
    isUpdating = true;
    CepEditText.this.setText(cep);

    CepEditText.this.setSelection(positioning[length]);

    }

    public void beforeTextChanged(CharSequence s, int start, int count,
    int after) {

    }

    public void onTextChanged(CharSequence s, int start, int before,
    int count) {

    }
    });
    }

    protected String padNumber(String number, int maxLength) {
    String padded = new String(number);
    for (int i = 0; i < maxLength – number.length(); i++)
    padded += " ";
    return padded;

    }

    private final KeylistenerNumber keylistenerNumber = new KeylistenerNumber();

    private class KeylistenerNumber extends NumberKeyListener {

    public int getInputType() {
    return InputType.TYPE_CLASS_NUMBER
    | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;

    }

    @Override
    protected char[] getAcceptedChars() {
    return new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8',
    '9' };

    }
    }
    }

Leave a Reply