Como criar mascara do EditText em Kotlin
Kotlin

Como criar mascara do EditText em Kotlin





Nesse tutorial vamos ver como criar mascara do EditText em Kotlin para que assim o usuário possa ter uma aplicação mais elegante.

Neste tutorial vamos criar um aplicativo que faz a mascara de texto em cpf ou cnpj de acordo com a opção do usuário.

Montando a base da aplicação

Primeiramente vamos criar um projeto vazio(Empty) com o nome de br.com.uware.edittextmask para que possamos criar as mascaras no EditText.

Logo depois de ter criado o projeto vamos deixar certo a base dele editando alguns arquivos como strings.xml e colors.xml.

Vamos então adicionar 3 cores ao nosso arquivo de colors para que possamos fazer a checagem se o número está correto. Então modificar para verde se correto, se incorreto modifica para vermelho.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#6200EE</color>
    <color name="colorPrimaryDark">#3700B3</color>
    <color name="colorAccent">#03DAC5</color>

    <color name="black">#000</color>
    <color name="green">#00AB07</color>
    <color name="red">#FF0000</color>

</resources>

Em nosso arquivo de strings vamos inserir as strings que o aplicativo irá usar para enviar as mensagens necessárias ao usuário.

<resources>
    <string name="app_name">EditTextMask</string>

    <string name="title">Escolha a opção e digite.</string>
    <string name="err_selection">Precisa escolher uma opção.</string>
    <string name="cpf">CPF</string>
    <string name="cnpj">CNPJ</string>
</resources>

Então com a base de nosso projeto pronta vamos começar a fazer as modificações em nossa activity_main.xml para depois fazer o nosso código que irá criar a mascara do EditText.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_margin="16dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/title"
            android:textSize="30dp"
            android:gravity="center"
            android:layout_marginBottom="30dp"/>
        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center">
            <RadioButton
                android:id="@+id/rdbCpf"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/cpf"
                android:layout_marginEnd="10dp"/>
            <RadioButton
                android:id="@+id/rdbCnpj"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/cnpj" />
        </RadioGroup>
        <EditText
            android:id="@+id/etInfo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/black"
            android:inputType="number"/>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>




Como criar mascara do EditText em Kotlin

Agora com os arquivos xml de nosso projeto feitos vamos dar início a parte da programação.

Vamos então modificar o nosso arquivo de MainActivity.kt para que receba o valor digitado no EditText e faça as modificações de acordo com a mascara escolhida.

package br.com.uware.edittextmask

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        etInfo.addTextChangedListener(object : TextWatcher {
            var isUpdating: Boolean = false
            override fun afterTextChanged(s: Editable) {
            }
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
            }
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                // Variáveis de strings
                val str = unmask(s.toString())
                var mascara = ""
                var mask = ""

                // Setando a mascara
                if(rdbCpf.isChecked) mask = "###.###.###-##"
                else if(rdbCnpj.isChecked) mask = "##.###.###/####-##"
                else {
                    mask = ""
                    Toast.makeText([email protected], R.string.err_selection, Toast.LENGTH_SHORT).show()
                }

                // Checa se está sendo feito update, para não entrar em loop infinito
                if (isUpdating) {
                    isUpdating = false
                    return
                }

                // Checa mascara e cria string com base na mascara
                var i = 0
                for (m in mask.toCharArray()) {
                    if (m != '#' && count > before) {
                        mascara += m
                        continue
                    }
                    try {
                        mascara += str[i]
                    } catch (e: Exception) {
                        break
                    }
                    i++
                }

                // Faz o update da string no EditText e verifica se está completa, colorindo se válido ou não
                isUpdating = true
                etInfo.setText(mascara)
                etInfo.setSelection(mascara.length)
                if(rdbCpf.isChecked) {
                    if (str.length >= 11) {
                        if(checkCpf(str)) etInfo.setTextColor(ContextCompat.getColor([email protected], R.color.green))
                        else etInfo.setTextColor(ContextCompat.getColor([email protected], R.color.red))
                    }
                    else etInfo.setTextColor(ContextCompat.getColor([email protected], R.color.black))
                }
                if(rdbCnpj.isChecked) {
                    if (str.length >= 14) {
                        if(checkCnpj(str)) etInfo.setTextColor(ContextCompat.getColor([email protected], R.color.green))
                        else etInfo.setTextColor(ContextCompat.getColor([email protected], R.color.red))
                    }
                    else etInfo.setTextColor(ContextCompat.getColor([email protected], R.color.black))
                }
            }

        })
    }
    // Função que retira a mascara para checar
    fun unmask(s: String): String {
        return s.replace("-", "").replace("/","").replace(".", "")
    }
    // Função que checa validade de CPF
    fun checkCpf(str: String): Boolean{
        var calc: Int
        var num = 10
        var sum = 0
        for(x in 0..8) {
            calc = str[x].toString().toInt() * num
            sum += calc
            --num
        }
        var rest = sum % 11
        var test = 11 - rest
        if(test > 9) test = 0
        if(test != str[9].toString().toInt()) return false
        num = 11
        sum = 0
        for(x in 0..9) {
            calc = str[x].toString().toInt() * num
            sum += calc
            --num
        }
        rest = sum % 11
        test = 11 - rest
        if(test > 9) test = 0
        if(test != str[10].toString().toInt()) return false
        return true
    }
    // Função que checa validade de CNPJ
    fun checkCnpj(str: String): Boolean{
        var calc: Int
        var num = 5
        var sum = 0
        for(x in 0..11) {
            calc = str[x].toString().toInt() * num
            sum += calc
            --num
            if(num == 1) num = 9
        }
        var rest = sum % 11
        var test = 11 - rest
        if(test < 2) test = 0
        if(test != str[12].toString().toInt()) return false
        num = 6
        sum = 0
        for(x in 0..12) {
            calc = str[x].toString().toInt() * num
            sum += calc
            --num
            if(num == 1) num = 9
        }
        rest = sum % 11
        test = 11 - rest
        if(test < 2) test = 0
        if(test != str[13].toString().toInt()) return false
        return true
    }
}

Podemos ver que em nosso arquivo contém função que retira a mascara e duas funções para checar a validade do CPF/CNPJ.

E também contém uma função de addTextChangedListener que irá checar a mudança em nosso EditText fazendo as modificações necessárias na string para inserir a mascara e quando tiver completa irá checar sua validade.

Enfim espero poder ter ajudado com mais este tutorial sobre como criar mascara do EditText em Kotlin.

Se tiver alguma dúvida a mais de uma olhada no site Android Developer.





Rodrigo Leutz
Desenvolvedor Web e Android ( Kotlin e Java )
https://uware.com.br