Change an Edittext mask at runtime

Asked

Viewed 10,087 times

4

I have a EditText which is used for CPF and CNPJ. I need to use it time as CNPJ and time as CPF.

I need to change the mask at runtime according to the selected type (CNPJ/CPF), but in doing so, a Exception is generated.

if(TipoPesso == FISICA){
  mEdtCGC.addTextChangedListener(Mask.insert("###.###.###-##", mEdtCGC));
}else{
  mEdtCGC.addTextChangedListener(Mask.insert("##.###.###/####-##", mEdtCGC));
}

There is the possibility of using two types of mask in the same EditText, alternating at runtime?

  • 4

    You can [Edit] the question and show the exception?

  • 3

    Can’t show you have 2 fields and show only 1 of them at the time you need ?

  • 1

    I found the solution to my problem. https://andremrezende.wordpress.com/tag/android-mask-mascara-edittext-java-layout-cpf-cnpj/

2 answers

13


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

Here is the code of the Mask class. With the difference that it will work also while deleting characters. It took almost 2 days to implement this function properly. It’s well tested now.

Use that class like this:

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

If you like the answer mark it as accepted!

  • Thank you very much man, me here killing myself, thinking that when I was erasing the data, it was something in afterTextChanged. I feel bad copying and pasting your kkk code

  • @Danielbeltrami I’m glad he helped you xD

5

Solution

Import the . java to your project, take a look in that class.

You can use it this way:

seuEditText.addTextChangedListener(Mask.insert(Mask.MaskType.CNPJ,  seuEditText));

//Ou

seuEditText.addTextChangedListener(Mask.insert(Mask.MaskType.CPF, seuEditText)); 

Browser other questions tagged

You are not signed in. Login or sign up in order to post.