Allow only selected charcters based on regex in an EditText
Asked Answered
N

4

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?

Newsstand answered 15/11, 2010 at 1:31 Comment(3)
possible duplicate of Android: How can I validate EditText input?. See also this question.Psychasthenia
Based on a regex? Do you mean just a list of allowed characters? That's not a regex.Nadbus
@Nadbus This is it - [[\\d]\\,\\+]*Newsstand
N
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.

Newsstand answered 15/11, 2010 at 16:57 Comment(1)
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); } } }Tracey
N
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.

Naamana answered 19/7, 2020 at 15:37 Comment(0)
C
1

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

Casaleggio answered 15/11, 2010 at 1:39 Comment(0)
O
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() ?: "")
  }
})
Omsk answered 12/10, 2020 at 14:35 Comment(2)
from your first line: You can use an IntentFilter for advanced filtering: It should be InputFilter right?Nimbostratus
@ShailendraMadda Yes it was a typo. I fixed it now, thank you :)Omsk

© 2022 - 2024 — McMap. All rights reserved.