title: Dynamic mask for EditText using TextWatcher (for Blood Pressue unit)
body: <p>I want to mask <code>EditText</code> for Blood Pressure unit, for example (###/###).</p>
  
  <p>value can be <code>2digits/2digits</code> or <code>3digits/3digits</code> or <code>3digits/2digits</code> or <code>2digits/3digits</code></p>
  
  <p>Currently I'm using below code which is working fine for <code>2digits/2digits</code> or <code>3digits/3digits</code> or <code>3digits/2digits</code> not working for <code>2digits/3digits</code>.</p>
  
  <p><strong>here is my code:</strong></p>
  
  <pre><code>import android.text.Editable
  import android.text.TextUtils
  import android.text.TextWatcher
  import android.widget.EditText
  import com.google.android.material.textfield.TextInputLayout
  
  object EditTextBPMask {
      private const val mask22 = "##/##"
      private const val mask32 = "###/##"
      private const val mask33 = "###/###"
  
      fun unmask(s: String): String {
          return s.replace("[^0-9]*".toRegex(), "")
      }
  
      fun insert(editText: EditText): TextWatcher {
          return object : TextWatcher {
              var isUpdating: Boolean = false
              var old = ""
  
              override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                  val str = unmask(s.toString())
                  val mask: String
                  val defaultMask = getDefaultMask(str)
                  mask = when (str.length) {
                      6 -&gt; mask33
                      5 -&gt; mask32
                      else -&gt; defaultMask
                  }
  
                  var mascara = ""
                  if (isUpdating) {
                      old = str
                      isUpdating = false
                      return
                  }
                  var i = 0
                  for (m in mask.toCharArray()) {
                      if (m != '#' &amp;&amp; str.length &gt; old.length || m != '#' &amp;&amp; str.length &lt; old.length &amp;&amp; str.length != i) {
                          mascara += m
                          continue
                      }
  
                      try {
                          mascara += str[i]
                      } catch (e: Exception) {
                          break
                      }
  
                      i++
                  }
                  isUpdating = true
                  editText.setText(mascara)
                  editText.setSelection(mascara.length)
                  /*if (isValid(editText)) {
                      editText.error = null
                  }
                  else {
                      editText.error = "Incorrect value!"
                  }*/
              }
  
              override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
              override fun afterTextChanged(s: Editable) {}
          }
      }
  
      private fun getDefaultMask(str: String): String {
          var defaultMask = mask22
          if (str.length &gt; 6) {
              defaultMask = mask33
          }
          return defaultMask
      }
  
      fun isValid(editText: EditText): Boolean {
          return if (!TextUtils.isEmpty(editText.text.toString())) {
              unmask(editText.text.toString()).length &gt; 3
          }
          else {
              false
          }
      }
  
  }
  </code></pre>