segunda-feira, 26 de setembro de 2011

Máscara no EditText do Android

Olá povo,

Certo dia, um colega me perguntou se existia um EditText com máscara no Android. Apesar de ser uma coisa bem comum em aplicações Desktop, eu não conheço um meio fácil de obter o mesmo comportamento em Android. Na época, dei uma pesquisada e não achei o queria.
Durante as aulas de Android na Unibratec um aluno me perguntou novamente, e fui pesquisar. Como não achei nada tão fácil, o jeito foi implementar um listener (observer) para quando o texto do EditText é alterado. A interface que faz isso no Android é a TextWatcher.
O exemplo abaixo, mostra como fazer uma máscara para um campo de CEP. Passei como exercício para a turma, estender esse exemplo para CPF e CNPJ. Eles fizeram. E vocês?


final EditText edt =
(EditText)findViewById(R.id.editText1);

edt.addTextChangedListener(new TextWatcher() {

boolean isUpdating;

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

@Override
public void onTextChanged(
CharSequence s, int start, int before, int after) {

// Quando o texto é alterado o onTextChange é chamado
// Essa flag evita a chamada infinita desse método
if (isUpdating){
isUpdating = false;
return;
}

// Ao apagar o texto, a máscara é removida,
// então o posicionamento do cursor precisa
// saber se o texto atual tinha ou não, máscara
boolean hasMask =
s.toString().indexOf('.') > -1 ||
s.toString().indexOf('-') > -1;

// Remove o '.' e '-' da String
String str = s.toString()
.replaceAll("[.]", "")
.replaceAll("[-]", "");

// as variáveis before e after dizem o tamanho
// anterior e atual da String, se after > before
// é pq está apagando
if (after > before) {
// Se tem mais de 5 caracteres (sem máscara)
// coloca o '.' e o '-'
if (str.length() > 5) {
str =
str.substring(0, 2) + '.' +
str.substring(2, 5) + '-' +
str.substring(5);

// Se tem mais de 2, coloca só o ponto
} else if (str.length() > 2) {
str =
str.substring(0, 2) + '.' +
str.substring(2);
}
// Seta a flag pra evitar chamada infinita
isUpdating = true;
// seta o novo texto
edt.setText(str);
// seta a posição do cursor
edt.setSelection(edt.getText().length());

} else {
isUpdating = true;
edt.setText(str);
// Se estiver apagando posiciona o cursor
// no local correto. Isso trata a deleção dos
// caracteres da máscara.
edt.setSelection(
Math.max(0, Math.min(
hasMask ? start - before : start,
str.length() ) ) );
}
}

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


4br4ç05,
nglauber

4 comentários:

Oraculum disse...

uma outra opção parecida seria isso aqui:

http://oraculum.blog.br/blogoraculum/index.php/2011/08/28/mascara-de-telefone-br-para-campos-edittext-no-android/

Artenes disse...

Muito obrigado por relatar tua experiência na WEB. Assim pessoas que estão passando pelo mesmo problema, como eu, podem ter uma base melhor para conseguir alcançar seu objetivo. Muito obrigado pela dica, funcionou muito bem comigo e o método que você usou é bem simples e direto. Valeu!

InfoDicas disse...

Boa, muito bem explicado, que Deus continue lhe abençoando e você viva tudo o que Ele sonhou para você, abraços.

Nelson Glauber disse...

Deus te ouça! Amém! ;)