13

I have a EditText field, variable name valueInputField.

I listen to the text input change, what I want to achieve is during inputting, when the input format DOESN'T matches a regular expression, I would like to stop showing more inputs, but keep the field focused & user is able to type on keyboard still just that no real effect will take to the field.

@OnTextChanged(R.id.value_input)
protected void onTextChanged(CharSequence charSequence) {
   String inputChars = charSequence.toString().trim();
   // if doesn't match regular expression, stop showing more inputs
   if (!inputChars.matches(MY_REGEXP)) {
      // this doesn't achieve what I need.
      valueInputField.setInputType(0)
   }
}

I tried above way, it doesn't work. How to achieve what I need?

8
  • 2
    setting android:maxLength="3"'in XML will do the thing you want. Commented Jun 13, 2018 at 9:09
  • valueInputField.requestFocus();but really you don't have to do all these stuff, Vir is right Commented Jun 13, 2018 at 9:10
  • Actually, sorry, I asked wrongly, I updated my question now. Commented Jun 13, 2018 at 9:11
  • You need to implement public void beforeTextChanged(CharSequence s, int start, int count, int after) Commented Jun 13, 2018 at 9:26
  • 1
    Can you please give your whol code and what kind of output you want Commented Jun 15, 2018 at 12:05

6 Answers 6

3

maybe you should try below logic

maxLength=inputChars.length
if (!inputChars.matches(MY_REGEXP)) {
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
}

above program will set a max length of EditText when it does not match regexp.

Sign up to request clarification or add additional context in comments.

2 Comments

The user will still be able to use backspace or change text after using backspace
Apparently, this is the answer the SO is looking for. See the comments section of my answer.
2
+25

You have to add an InputFilter to your textView:

here's an example:

editText.filters = arrayOf(object: InputFilter {
   override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence {
      if (Regex("[0-9]*").matches(source!!)) {
         return source
      } else {
         return source.subSequence(start, end-1)
      }
   }
})

This filter method gets called everytime the input in the editText is being invoked. You can return the source when it matches a regex, otherwise, you can return a subSequence of the source, without the last char inserted.

The code example is in Kotlin, the translation shouldn't give you any problem :)

2 Comments

please take note that source will always give you all the characters typed so far
@user1506104 that's why I match the source with the regex, the entire input needs to match the pattern
2

You are already doing setInputType(InputType.TYPE_NULL). But it should be used with withsetEnabled(false) to get it worked.

This will change the background color too. It is highly recommended because it gives the user a clue that it won't accept input. However you can change it as setBackgroundColor(Color.TRANSPARENT) if you wish.

If you want to hide the cursor, add setCursorVisible(false).

Alternatively you can use afterTextChanged instead of onTextChanged so that you will be able to manipulate the text.

Comments

1

If you want to stop suggestions in edit text you should try something like:

editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

And to enable again after any condition use this:

editText.setInputType(InputType. TYPE_CLASS_TEXT);

Here is an example with input with a threshold of size, here should work with your regex too:

editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if(s.length()< threshold){
                editText.setInputType(InputType. TYPE_CLASS_TEXT);
            }
            if(s.length()>= threshold){
                editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

1 Comment

@Leem is this help you?
1

Disabling the input type for edit text does not work properly when its focussed or being edited. Once you set the inout type to null, the view will start to receive the keypress callback methods. So, have class variable to validate the field and cancel the keys pressed. Here sample code goes.

public class SplashActivity extends AppCompatActivity{

    EditText valueInputField;
    private  boolean allowValueField2Edit = true;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ....

        valueInputField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2{
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                String inputChars = charSequence.toString().trim();
                // if doesn't match regular expression, stop showing more inputs
                if (!inputChars.matches(MY_REGEXP)) {

                    // this doesn't achieve what I need.
                    valueInputField.setInputType(InputType.null);
                    allowValueField2Edit = false;
                }

            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });

      //Once you set the input type to none fore edit control, on Key lister will receive callbacks
        valueInputField.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
             //Here, you can add your custom logic to have key actions.
            //retrun false will have key effect, return true 
                return !allowValueField2Edit;
            }
        });

Hope this helps...

2 Comments

this will not work for soft keyboard stackoverflow.com/questions/3697063/…
On key listener will work once you make edit text field input type to null or disabled. I agree it does not work in editing mode.
0

Pseudocode:

  1. wait for the input text to match your pattern
  2. when match is found, setup filter
  3. filter will need to return the same previous string on every key press

Source code:

editText.addTextChangedListener(new TextWatcher() {
    ...
    @Override
    public void afterTextChanged(Editable editable) {
        String text = editable.toString();

        // STEP 1
        if(text.matches(myRegex) && !flag) {

            // make sure that this code block is executed only once
            flag = true;

            // STEP 2
            // when match is found, always return the same string
            // therefore disabling further editing of the editText field
            editText.setFilters(new InputFilter[]{
                new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence charSequence, int i, int i1, 
                            Spanned spanned, int i2, int i3) {
                        // STEP 3
                        return spanned.subSequence(i2, i3);
                    }
                }
            });
        }
    }
});

When setting input filter, please take note of the proper way to do it. Please check this SO answer by Steven Byle.

2 Comments

I run this code, but the keyboard delete button looses its effect. User is not able to delete input.
I thought you said "disable EditText inputs". If no, then setting maxlength on match should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.