Как мгновенно удалить ПРОБЕЛ из текста редактирования, если пользователь нажимает пробел?

У меня есть edittext и textwatcher, который следит за тем, прибыл ли SPACE или нет. Если это ПРОБЕЛ, я хотел бы удалить это немедленно. Или, если это пробел, я хочу убедиться, что он не отображается, но как-то указать (seterror, toast) для пользователя, что пробел не разрешен.

edittext.addTextChangedListener(new TextWatcher() {

    public void afterTextChanged(Editable s) {

                   //---//
                  }
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {}
        }); 

Я не могу определить onkeydown в методе afterTextChaned, так как это выдает ошибку.

 public boolean onKeyDown(int keyCode, KeyEvent event) {
                super.onKeyDown(keyCode, event);

                if (keyCode == KeyEvent.KEYCODE_SPACE) {

                }
    }

Так что это не работает (синтаксическая ошибка, неуместная конструкция для int keyCode.

Заранее спасибо!


person Jani Bela    schedule 18.03.2012    source источник
comment
что за ошибка, которую вы упомянули?   -  person dldnh    schedule 18.03.2012
comment
В логарифме нет ошибок, это простая синтаксическая ошибка.   -  person Jani Bela    schedule 18.03.2012
comment
Вы хотите показать введенный символ пробела then и удалить его, или вы просто хотите убедиться, что пользователь не вводит пробелы в EditText?   -  person user    schedule 18.03.2012
comment
Я хочу убедиться, что пользователь не вводит пробел, но если это произойдет, я хочу, чтобы для edittext появилось сообщение об ошибке (сообщение seterror). В моем случае не очевидно, что SPACE нельзя использовать, поэтому я хотел бы предупредить пользователя, если он / она использует SPACE.   -  person Jani Bela    schedule 18.03.2012


Ответы (7)


Решение, как обычно, намного проще:

@Override
public void afterTextChanged(Editable s) {
    String result = s.toString().replaceAll(" ", "");
    if (!s.toString().equals(result)) {
         ed.setText(result);
         ed.setSelection(result.length());
         // alert the user
    }
}

Это не должно иметь проблем предыдущих попыток.

person user    schedule 18.03.2012
comment
Хорошо, как насчет этого, я просто вставлю this line with spaces в текстовое поле? А теперь что? :D (Я не пытаюсь быть злым, :) Я не уверен, поэтому я спрашиваю... Возможно, вы захотите проверить всю строку на наличие пробелов. - person st0le; 18.03.2012
comment
@st0le Мой код был только для случая, когда пользователь вводит текст посимвольно. Я отредактировал свой ответ. - person user; 18.03.2012
comment
Ваш первый код - это то, что мне нужно, но если я перейду к середине текста, появится пробел, поэтому он работает, только если курсор находится в конце текста. - person Jani Bela; 18.03.2012
comment
Второй код у меня не работает. Если я нажму пробел, он появится. - person Jani Bela; 18.03.2012
comment
@JaniBela Извините, я забыл об этом случае. Я обновил свой ответ более простым решением, которое должно работать, несмотря ни на что. - person user; 18.03.2012
comment
Просто всегда лучше ;-) Хорошее решение! - person Robert; 26.03.2014
comment
@zeeks Добавьте TextWatcher (для чего требуется реализовать 3 метода) в свой EditText, а затем добавьте код из моего ответа в метод afterTextChanged() TextWatcher. В вопросе вы можете увидеть, как добавить наблюдателя. - person user; 16.01.2016
comment
У меня этот метод точно не работает, телефон завис. клавиатура показывалась там бесконечно, даже если я закрыл это приложение. Нужно перезагрузить телефон! это на самом деле становится рекурсивным, на мой взгляд - person Jimit Patel; 01.07.2016
comment
@JimitPatel Я сомневаюсь, что простое использование кода, который я опубликовал (без каких-либо дополнительных добавлений), может показать поведение, о котором вы упоминаете. Пожалуйста, опубликуйте новый вопрос с вашим текущим кодом, перед этим попробуйте отладить приложение и посмотрите, что вы получите в виде текста в TextWatcher. - person user; 01.07.2016
comment
@Luksprog, я использую ваш фрагмент кода в сочетании с RXjava - person Jimit Patel; 01.07.2016
comment
@JimitPatel Вам обязательно следует опубликовать новый вопрос (вместе с кодом RxJava, который вы используете), поскольку ваша проблема здесь выходит за рамки. - person user; 01.07.2016
comment
@Luksprog, возможно, вы правы, что удерживает меня от голосования против ваших ответов: D. Тем не менее, я записал в комментарии, потому что, если кто-то потерпит неудачу при использовании в будущем, они поймут и, вероятно, не позволят ему проголосовать против. - person Jimit Patel; 01.07.2016

setSelection нужно снова установить курсор в конце вашего EditText:

editText.addTextChangedListener(new TextWatcher() {

                @Override
                public void onTextChanged(CharSequence cs, int arg1, int arg2,
                        int arg3) {}
                @Override
                public void beforeTextChanged(CharSequence s, int arg1, int arg2,
                        int arg3) {}
                @Override
                public void afterTextChanged(Editable arg0) {
                    if(editText.getText().toString().contains(" ")){ editText.setText(editText.getText().toString().replaceAll(" " , ""));
                    editText.setSelection(editText.getText().length());

                    Toast.makeText(getApplicationContext(), "No Spaces Allowed", Toast.LENGTH_LONG).show();
                    }
                }});
person ORY    schedule 29.03.2016
comment
В вашем ответе опечатка? - person Richard Erickson; 29.03.2016

boolean editclicked =false ;

edittext.addTextChangedListener(new TextWatcher() {
    public void afterTextChanged(Editable s) {
        editclicked = false ;
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        editclicked = true;
    }); 

Поместите это как отдельную функцию:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (editclicked) {
        if (keyCode == KeyEvent.KEYCODE_SPACE) {
            return false
        }
    } else {
        super.onKeyDown(keyCode, event);
    }
}
person Harsh Dev Chandel    schedule 18.03.2012
comment
Я получаю сообщение об ошибке из-за закрывающего типа или чего-то подобного. - person Jani Bela; 18.03.2012

@Override
public void afterTextChanged(Editable s) {
    String result = s.toString().replaceAll("\\s", "");
    if (!s.toString().equals(result)) {
        int pos = editText.getSelectionStart() - (s.length() - result.length());
        editText.setText(result);
        editText.setSelection(Math.max(0,Math.min(pos, result.length())));
        editText.setError("No spaces allowed");
    }
}

\s соответствует любому пробельному символу (равному [\r\n\t\f\v ])

Установка выделения таким образом позволяет вам вводить или вставлять текст в середине текста редактирования без потери позиции курсора.

person John    schedule 06.09.2017

Мое относительно простое решение для мгновенного удаления пробелов без удаления spannables (стилей) в EditText:

  1. Удалить в начале:

        @Override
    public void afterTextChanged(Editable s) {
        int i;
        for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
        s.replace(0, i, "");
    }
    

В основном это все, но вы также можете сделать следующее:

  1. Удалить при запуске (не прерывая первый ввод):

        @Override
    public void afterTextChanged(Editable s) {
        String text = s.toString();
        if(!text.trim().isEmpty()){
            int i;
            for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
            s.replace(0, i, "");
        }
    }
    

  1. Удаление в начале и в конце (разрешить 1 пробел в конце для удобного ввода):

        @Override
    public void afterTextChanged(Editable s) {
        int i;
        //remove at start
        for (i = 0; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { ; }
        s.replace(0, i, "");
        //remove at end, but allow one whitespace character
        for (i = s.length(); i > 1 && Character.isWhitespace(s.charAt(i-1)) && Character.isWhitespace(s.charAt(i-2)); i--) { ; }
        s.replace(i, s.length(), "");
    }
    
person JacksOnF1re    schedule 19.10.2017

Для мгновенного удаления пробела вы можете добиться этого двумя способами.

Одно простое решение: вы можете установить цифры в свой текст редактирования.

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 

второй способ вы можете установить фильтр

EditText.setFilters(new InputFilter[] { filter });


InputFilter filter = new InputFilter() {
 public CharSequence filter(CharSequence source, int start, int end,
   Spanned dest, int dstart, int dend) {
  for (int i = start; i < end; i++) {
   if (Character.isSpaceChar(source.charAt(i))) {
    return "";
   }
  }
  return null;


      }
     }
person King of Masses    schedule 22.04.2016
comment
Обратите внимание, что возвращать null здесь правильно, если вы хотите сохранить текст как есть, несмотря на то, что это самая запутанная вещь. Я не могу дождаться, чтобы изучить Kotlin... - person lustig; 05.07.2017

Еще один простой способ добиться этого с помощью входного фильтра

editText.setFilters(new InputFilter[]{new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (source.toString().equalsIgnoreCase(" ")){
                return "";
            }
            return source;
        }
    }});

Это немедленно удалит пространство, введенное пользователем, и создаст впечатление, что пространство отключено.

person PranavKAndro    schedule 26.09.2017