Blog do VG

Codificar é uma arte, mas nem todo mundo é um artista.

AndroidProgramação

Mascara de CPF e CNPJ no Android

Fala galerinha, tudo sussa?

Essa semana um visitante do blog me perguntou o que eu usava para tratar máscara de CPF e CNPJ no Android, já que as opções de máscaras nativas do Android não atendem a essa necessidade dos desenvolvedores do Brasil, passei uma soluçãozinha que uso a muito tempo pra ele e lembrei que eu não tinha postado nada relacionado por aqui ainda, a minha solução se baseia na classe TextWatcher, esta classe está disponível desde a API 1, quando um objeto de TextWatcher é adicionado a um Editable, faz os métodos do TextWatcher serem chamados quando o texto do editable é mudado, então, basicamente o que eu faço é adicionar ou remover a máscara conforme o usuário altera o texto.

O código da classe, bem como um projeto de exemplo podem ser encontrados no meu GitHub, mas pra facilitar a vida de vocês eu também vou colocar ele abaixo.

 

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


public class MaskUtil {

    private static final String CPFMask = "###.###.###-##";
    private static final String CNPJMask = "##.###.###/####-##";

    public static String unmask(String s) {
        return s.replaceAll("[^0-9]*", "");
    }

    private static String getDefaultMask(String str) {
        String defaultMask = CPFMask;
        if (str.length() == 14){
            defaultMask = CNPJMask;
        }
        return CPFMask;
    }

    public static TextWatcher insert(final EditText editText, final MaskType maskType) {
        return new TextWatcher() {

            boolean isUpdating;
            String oldValue = "";

            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String value = MaskUtil.unmask(s.toString());
                String mask;
                switch (maskType) {
                    case CPF:
                        mask = CPFMask;
                        break;
                    case CNPJ:
                        mask = CNPJMask;
                        break;
                    default:
                        mask = getDefaultMask(value);
                        break;
                }

                String maskAux = "";
                if (isUpdating) {
                    oldValue = value;
                    isUpdating = false;
                    return;
                }
                int i = 0;
                for (char m : mask.toCharArray()) {
                    if ((m != '#' && value.length() > oldValue.length()) || (m != '#' && value.length() < oldValue.length() && value.length() != i)) {
                        maskAux += m;
                        continue;
                    }

                    try {
                        maskAux += value.charAt(i);
                    } catch (Exception e) {
                        break;
                    }
                    i++;
                }
                isUpdating = true;
                editText.setText(maskAux);
                editText.setSelection(maskAux.length());
            }

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

Pra usar esta belezinha, uma vez que você já tenha o objeto do EditText simplesmente adicione o listener e o tipo de máscara e a classe faz o resto.

        etCPF.addTextChangedListener(MaskUtil.insert(etCPF, MaskType.CPF));
        etCNPJ.addTextChangedListener(MaskUtil.insert(etCNPJ, MaskType.CNPJ));

O Enum é bem simples.

public enum  MaskType {
    CPF,
    CNPJ
}

Esta classe pode ser adaptada para qualquer máscara, bastando criar um novo formato na classe MaskUtil e alterar o método onTextChanged do TextWatcher, além de criar um novo valor no enum MaskType.

Molezinha né? qualquer dúvida comenta aí, que eu respondo o mais rápido possível, ou não.

vanderson

Analista/Desenvolvedor de Sistemas, Gamer, Blogger e um jogador de futebol praticamente profissional (no vídeogame).