Отключить ввод EditText, сохраняя при этом фокусировку

У меня есть поле EditText, имя переменной valueInputField.

Я слушаю изменение ввода текста, чего хочу достичь во время ввода, когда формат ввода НЕ соответствует регулярному выражению, я хотел бы прекратить показывать больше входов, но сохранить фокусировку поля и пользователь может набрать клавиатура все еще только, что никакой реальный эффект не выйдет на поле.

@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)
   }
}

Я пробовал выше, это не работает. Как достичь того, что мне нужно?

Ответ 1

Вы должны добавить InputFilter в свой textView:

вот пример:

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)
      }
   }
})

Этот метод фильтра вызывается каждый раз, когда вызывается вход в editText. Вы можете вернуть исходный код, когда он соответствует регулярному выражению, в противном случае вы можете вернуть subSequence источника без последнего вставленного символа.

Пример кода в Kotlin, перевод не должен давать вам никаких проблем :)

Ответ 2

Вы уже используете setInputType(InputType.TYPE_NULL). Но он должен использоваться с setEnabled(false) чтобы заставить его работать.

Это также изменит цвет фона. Это настоятельно рекомендуется, поскольку дает пользователю понять, что он не будет принимать входные данные. Однако вы можете изменить его как setBackgroundColor(Color.TRANSPARENT) если хотите.

Если вы хотите скрыть курсор, добавьте setCursorVisible(false).

В качестве альтернативы вы можете использовать afterTextChanged вместо onTextChanged чтобы вы могли манипулировать текстом.

Ответ 3

возможно, вы должны попробовать ниже логики

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

выше программа установит максимальную длину EditText, если она не соответствует регулярному выражению.

Ответ 4

Отключение ввода типа для редактирования текста не работает должным образом, когда его фокусировка или редактирование. После того, как вы установите для типа inout значение null, представление начнет принимать методы обратного вызова нажатия клавиши. Итак, у меня есть переменная класса для проверки поля и отмены нажатых клавиш. Вот пример кода.

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;
            }
        });

Надеюсь это поможет...

Ответ 5

Если вы хотите остановить предложения в текстовом редакторе, вы должны попробовать что-то вроде:

editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

И чтобы включить снова после любого условия, используйте это:

editText.setInputType(InputType. TYPE_CLASS_TEXT);

Вот пример с вводом с порогом размера, здесь также следует работать с вашим регулярным выражением:

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) {

        }
    });

Ответ 6

Метод matcher lookingAt() работает как метод matches() с одним существенным отличием. Метод lookAt() соответствует только регулярному выражению в начале текста, а match() соответствует регулярному выражению для всего текста. Другими словами, если регулярное выражение соответствует началу текста, но не всему тексту, lookAt() вернет true, а match() вернет false.

Вот пример Matcher.lookingAt():

        String text = "This is the text to be searched " + "for occurrences of the http:// pattern.";
        String patternString = "This is the";

        Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(text);

        String lookingat = ("lookingAt = " + matcher.lookingAt());
        String matches=  ("matches   = " + matcher.matches());

Этот пример соответствует регулярному выражению "this is" как от начала текста, так и от всего текста. Согласование регулярного выражения с началом текста (lookAt()) вернет true.

Согласование регулярного выражения со всем текстом (matches()) вернет false, потому что текст имеет больше символов, чем регулярное выражение. Регулярное выражение говорит, что текст должен соответствовать тексту "Это точно", без дополнительных символов до или после выражения.

Ответ 7

псевдокод:

  1. дождитесь, пока текст ввода будет соответствовать вашему шаблону
  2. когда совпадение найдено, установите фильтр
  3. фильтр должен будет вернуть одну и ту же предыдущую строку при каждом нажатии клавиши

Исходный код:

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);
                    }
                }
            });
        }
    }
});

При настройке входного фильтра, пожалуйста, обратите внимание на правильный способ его выполнения. Пожалуйста, проверьте этот ответ от Стивена Байла.