9

I want to allow users only to type certain characters based on the a regex in my android applications. How do I achieve it?

Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
  • 1
    possible duplicate of [Android: How can I validate EditText input?](http://stackoverflow.com/questions/2763022/android-how-can-i-validate-edittext-input). See also [this question](http://stackoverflow.com/questions/1151664). – Matt Ball Nov 15 '10 at 01:37
  • Based on a regex? Do you mean just a list of allowed characters? That's not a regex. – Falmarri Nov 15 '10 at 16:00
  • @Falmarri This is it - [[\\d]\\,\\+]* – Ragunath Jawahar Nov 15 '10 at 16:52

4 Answers4

14

Used a TextWatcher as @Matt Ball suggested.

@Override
public void afterTextChanged(Editable s) {
      String text = s.toString();
      int length = text.length();

      if(length > 0 && !Pattern.matches(PATTERN, text)) {
           s.delete(length - 1, length);
      }
}

Edit Although the TextWatcher works, it would be cleaner to use an InputFilter. Check this example.

Community
  • 1
  • 1
Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
  • This helped me a lot, thanks I just got a problem when the user deleted a character and it didn't enter the PATTERN was crashing because an out of bounds so you can use this (with some modifications for my app) if(text.length()>0) { int length = text.length(); if (!getPattern().equals("")) { if (!Pattern.matches(getPattern(),text)) { s.delete(length - 1, length); } } } – magorich Jan 19 '16 at 01:18
2

You could use android:digits on the xml EditText instead of using a regex.

For your allowed chars of the regex (numbers, comma and plus symbol): android:digits="0123456789,+"

And you could use a string resource as the digits value in case you want to reuse it.

jeprubio
  • 17,312
  • 5
  • 45
  • 56
1

Try this: If the character to type matches /[a-zA-Z0-9{insert valid characters here}]/ then allow it, otherwise don't.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
1

You can use an InputFilter for advanced filtering:

class CustomInputFilter : InputFilter {

  private val regex = Pattern.compile("^[A-Z0-9]*$")

  override fun filter(
    source: CharSequence,
    start: Int,
    end: Int,
    dest: Spanned?,
    dstart: Int,
    dend: Int
  ): CharSequence? {
    val matcher = regex.matcher(source)
    return if (matcher.find()) {
      null
    } else {
      ""
    }
  }
}

And then add it to an EditText or TextInputEditText like this:

textInputLayout.editText!!.filters += CustomInputFilter()
//or
editText.filters += CustomInputFilter()

Remember that if you have a TextWatcher this will not prevent the TextWatcher to fire, you can filter out those events checking if the previous and next text values are the same.

Something like:

//addTextChangedListener is an extension function available in core-ktx library
textInputLayout.editText!!.addTextChangedListener(afterTextChanged = { editable ->
  val editTextValue = viewModel.editTextLiveData.value ?: ""
  if (!editTextValue.equals(editable)) {
    viewModel.updateEditTextValue(editable?.toString() ?: "")
  }
})
MatPag
  • 41,742
  • 14
  • 105
  • 114