Mascara de CPF para campos EditText no Android

oraculum

Tagged: , , ,

droid

Veja como fazer essa mascara ###.###.###-## no seu EditText

 

Veja a parte do código como fica:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package lethus.socialdroid.core.widgets;
 
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 CpfEditText extends EditText {
	private boolean isUpdating;
 
	/*
	 * Maps the cursor position from phone number to masked number... 12345678912
	 * => xxx.xxx.xxx-xx
	 */
	private int positioning[] = { 0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14 };
 
	public CpfEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initialize();
 
	}
 
	public CpfEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		initialize();
 
	}
 
	public CpfEditText(Context context) {
		super(context);
		initialize();
 
	}
 
	public String getCleanText() {
		String text = CpfEditText.this.getText().toString();
 
		text.replaceAll("[^0-9]*", "");
		return text;
 
	}
 
	private void initialize() {
 
		final int maxNumberLength = 11;
		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() > 11)
					number = number.substring(0, 11);
				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, 3);
				String part2 = paddedNumber.substring(3, 6);
				String part3 = paddedNumber.substring(6, 9);
				String part4 = paddedNumber.substring(9, 11);
 
				/* build the masked phone number... */
				String cpf = part1 + "." + part2 + "." + part3 + "-" + part4;
 
				/*
				 * Set the update flag, so the recurring call to
				 * afterTextChanged won't do nothing...
				 */
				isUpdating = true;
				CpfEditText.this.setText(cpf);
 
				CpfEditText.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' };
 
		}
	}
}

 

Veja a parte do XML como fica:

1
<lethus.socialdroid.core.widgets.CpfEditText android:id="@+id/txtCpf" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="number" />

 

Mais informações sobre como implementar essa mascara consulte o artigo da mascara de telefone

Share Button

14 Comments

  1. Filipe Bragança

    Muito bom sua dica cara.
    Parabéns e me ajudou bastante aqui.

    Reply

  2. 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.

    Reply

  3. 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.

    Reply

    • oraculum

      @Marcos Angelo, Vamos lá me envie aqui sua dúvida eu lhe ajudo sem problemas, você pode postar o seu código aqui no git que eu vejo e comento: https://gist.github.com/

      Reply

      • Marcos Angelo

        @oraculum,
        Boa tarde, na verdade estou com dificuldades em entender esse codigo para transformalo no formato do CGC(CNPJ) que seria assim: xx.xxx.xxx/xxxx-xx

        Desde ja grato.

        Reply

  4. Evandro

    Seria interessante na própria classe já fazer o calculo da validação do CPF, ou teria algum problema em relação a isto?

    Reply

  5. Evandro

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

    Reply

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

    }
    }
    }

    Reply

  7. Emanuel Eloy

    Muito bom amigo, funciona perfeitamente, parabéns. Pena que a Google ainda não já implementou essas classes como sendo nativas.

    Reply

  8. Roberto Silva

    package com.status.view;

    /*Fonte:
    * http://oraculum.blog.br/blogoraculum/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' };

    }
    }
    }

    Reply

    • Roberto Silva

      @Roberto Silva,
      Este código que postei é a alteração do exemplo do site p/Data, o DatePicker fica ocupando muito espaço na tela, para celular com resolução baixa ficava ruim.
      Agradeço pelo código, ajudou muito, distribuo sobre qual licença?

      Obrigado

      Reply

  9. 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.

    Reply

  10. Gustavo Costa

    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));

    Reply

Leave a Reply