14 Comments

  1. Danilo

    Seu tutorial me ajudou muito, obrigado. Pra melhorar o seu código, na linha 51 troque this.setText(” – “); por this.setText(” . . – “); eu fiz aqui no meu projeto e deu certo.

    VLW msm.

  2. Marcos Angelo

    Muito bom cara, parabens me ajudou muito essa dica sua, mas sera que dava para me dar uma ajudinha com o CGC(CNPJ)??

    Desde ja grato.

  3. Usando o arquivo fo CPF fiz para o CNPJ contudo não está funcionando é possível verificar o que está acontecendo?

    public class CnpjEditText extends EditText {
    private boolean isUpdating;

    /*
    * Maps the cursor position from phone number to masked number… 12345678912345 => xx.xxx.xxx/xxxx-xx
    */
    private int positioning[] = { 0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 18 };

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

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

    public CnpjEditText(Context context) {
    super(context);
    initialize();
    }

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

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

    private void initialize() {
    final int maxNumberLength = 14;
    this.setKeyListener(keylistenerNumber);

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

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

    if (isUpdating) {
    isUpdating = false;
    return;
    }

    String number = current.replaceAll(“[^0-9]*”, “”);
    if (number.length() > 14)
    number = number.substring(0, 14);
    int length = number.length();

    String paddedNumber = padNumber(number, maxNumberLength);

    String part1 = paddedNumber.substring(0, 2);
    String part2 = paddedNumber.substring(2, 5);
    String part3 = paddedNumber.substring(5, 8);
    String part4 = paddedNumber.substring(8, 12);
    String part5 = paddedNumber.substring(12, 14);

    String cnpj = part1 + “.” + part2 + “.” + part3 + “/” + part4 + “-” + part5;

    isUpdating = true;
    CnpjEditText.this.setText(cnpj);

    CnpjEditText.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' };
    }
    }
    }

  4. Jean Gabriel

    Parabens pelo tutorial. MUITO BOM!

    segue o codigo para CNPJ que a galera ta pedindo…

    package br.jan.celular.mascaras;

    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 maskCNPJ extends EditText {
    private boolean isUpdating;

    /*
    * Maps the cursor position from phone number to masked number… 12345678912
    * => xx.xxx.xxx/xxxx-xx
    */
    private int positioning[] = { 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14,15,17,18 };

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

    }

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

    }

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

    }

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

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

    }

    private void initialize() {

    final int maxNumberLength = 14;
    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() > 14)
    number = number.substring(0, 14);
    int length = number.length();

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

    /* Split CNPJ number into parts… */
    String part1 = paddedNumber.substring(0, 2);
    String part2 = paddedNumber.substring(2, 5);
    String part3 = paddedNumber.substring(5, 8);
    String part4 = paddedNumber.substring(8, 12);
    String part5 = paddedNumber.substring(12, 14);

    /* build the masked phone number… */
    String cnpj = part1 + “.” + part2 + “.” + part3 + “/” + part4+”-“+part5;

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

    maskCNPJ.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' };

    }
    }
    }

  5. package com.status.view;

    /*Fonte:
    * http://oraculum.blog.br/index.php/2012/02/29/mascara-de-cpf-para-campos-edittext-no-android/
    *
    * no xml fica assim:
    *
    * */

    import java.text.SimpleDateFormat;

    import com.status.controle.MessageBox;

    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.view.View;
    import android.widget.EditText;

    public class DataEditText extends EditText {
    private boolean isUpdating;

    /*
    * Maps the cursor position from date number to masked number…
    *
    * D D 2 M M 5 Y Y Y Y
    */
    private int positioning[] = { 0, 1, /*/*/ 3, 4, /*/*/ 6, 7, 8, 9, 10};

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

    }

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

    }

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

    }

    public String getCleanText() {
    String text = DataEditText.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.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {

    if(!hasFocus){
    if(DataEditText.this.getText().toString().length() > 0){
    try{
    SimpleDateFormat sf=new SimpleDateFormat(“dd/MM/yyyy”);
    sf.parse(DataEditText.this.getText().toString().trim());
    }catch(Exception e){
    e.printStackTrace();
    DataEditText.this.setText(” / / “);
    MessageBox.show(DataEditText.this.getContext(),”Atenção esta data não está valida,\n” +
    “o formato é: DD/MM/AAAA ,tente novamente.”);
    }
    }
    }else{
    DataEditText.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 8 characters… , coloca um espaço na proxima posição */
    String paddedNumber = padNumber(number, maxNumberLength);

    /* Split date number into parts…
    * 01234567
    * DDMMYYYY
    * or
    * 012345
    * DDMMYY
    * */
    String part1 = paddedNumber.substring(0, 2);//dia
    String part2 = paddedNumber.substring(2, 4);//mes
    String part3 = paddedNumber.substring(4, paddedNumber.length());//ano, pode se com 2 ou 4 digitos

    /* build the masked date number… */
    String date = part1 + “/” + part2 + “/” + part3 ;

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

    System.out.println(“Posição n°: “+length);

    DataEditText.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' };

    }
    }
    }

  6. Alexandre Marins

    Bom dia, Fiz o Tutorial e ao ajustar o meu XML esta dando erro no android:id=@+id/TxtCpf” o Erro é: aapt: Error parsing XML: not well-formed (invalid token), ja tentei de tudo e nao consigo resolver.

  7. import android.text.Editable;
    import android.text.TextWatcher;
    import android.widget.EditText;

    public abstract class Mask {
    public static String CPF_MASK = "###.###.###-##";
    public static String CELULAR_MASK = "(##) #### #####";
    public static String CEP_MASK = "#####-###";

    public static String unmask(String s) {
    return s.replaceAll("[.]", "").replaceAll("[-]", "")
    .replaceAll("[/]", "").replaceAll("[(]", "")
    .replaceAll("[)]", "").replaceAll(" ", "")
    .replaceAll(",", "");
    }

    public static boolean isASign(char c) {
    if (c == '.' || c == '-' || c == '/' || c == '(' || c == ')' || c == ',' || c == ' ') {
    return true;
    } else {
    return false;
    }
    }

    public static String mask(String mask, String text) {
    int i = 0;
    String mascara = "";
    for (char m : mask.toCharArray()) {
    if (m != '#') {
    mascara += m;
    continue;
    }
    try {
    mascara += text.charAt(i);
    } catch (Exception e) {
    break;
    }
    i++;
    }

    return mascara;
    }

    public static TextWatcher insert(final String mask, final EditText ediTxt) {
    return new TextWatcher() {
    boolean isUpdating;
    String old = "";

    public void onTextChanged(CharSequence s, int start, int before, int count) {
    String str = Mask.unmask(s.toString());
    String mascara = "";
    if (isUpdating) {
    old = str;
    isUpdating = false;
    return;
    }

    int index = 0;
    for (int i = 0; i < mask.length(); i++) {
    char m = mask.charAt(i);
    if (m != '#') {
    if (index == str.length() && str.length() < old.length()) {
    continue;
    }
    mascara += m;
    continue;
    }

    try {
    mascara += str.charAt(index);
    } catch (Exception e) {
    break;
    }

    index++;
    }

    if (mascara.length() > 0) {
    char last_char = mascara.charAt(mascara.length() - 1);
    boolean hadSign = false;
    while (isASign(last_char) && str.length() == old.length()) {
    mascara = mascara.substring(0, mascara.length() - 1);
    last_char = mascara.charAt(mascara.length() - 1);
    hadSign = true;
    }

    if (mascara.length() > 0 && hadSign) {
    mascara = mascara.substring(0, mascara.length() - 1);
    }
    }

    isUpdating = true;
    ediTxt.setText(mascara);
    ediTxt.setSelection(mascara.length());
    }

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

    public void afterTextChanged(Editable s) {}
    };
    }
    }

    Ae ta o codigo da classe Mask. Com a diferença que ele vai funcionar tbm enquanto estiver deletando os characters. Levei quase 2 dias para implementar essa função adequadamente. Ta bem testada jah.

    Use essa classe assim:

    EditedText etCPF = /* sua inicialização aqui */;
    etCPF.addTextChangedListener(Mask.insert(Mask.CPF_MASK, etCPF));

Leave a Reply