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
Filipe Bragança
Muito bom sua dica cara.
Parabéns e me ajudou bastante aqui.
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.
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.
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/
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.
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?
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' };
}
}
}
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' };
}
}
}
Emanuel Eloy
Muito bom amigo, funciona perfeitamente, parabéns. Pena que a Google ainda não já implementou essas classes como sendo nativas.
Roberto Silva
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' };
}
}
}
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
oraculum
@Roberto Silva, É mesmo faltou a licença, lança ai uma GNU GPL
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.
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));