Предотвратите ввод ключа в EditText, но все же покажите текст как многострочный

Как сделать EditText на Android таким образом, чтобы пользователь не мог вводить многострочный текст, но дисплей все еще многострочный (т.е. вместо переноса текста вправо есть перенос слов)?

Он похож на встроенное приложение SMS, в котором мы не можем вводить новую строку, но текст отображается в нескольких строках.

Ответ 1

Я бы подклассифицировал виджет и переопределил обработку ключевых событий, чтобы заблокировать ключ Enter:

class MyTextView extends EditText
{
    ...
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if (keyCode==KeyEvent.KEYCODE_ENTER) 
        {
            // Just ignore the [Enter] key
            return true;
        }
        // Handle all other keys in the default way
        return super.onKeyDown(keyCode, event);
    }
}

Ответ 2

Это метод, в котором вам не нужно переопределять класс EditText. Вы просто улавливаете и заменяете новые строки пустыми строками.

myEditTextObject.addTextChangedListener(new TextWatcher() {

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

    }

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

    }

    public void afterTextChanged(Editable s) {

        for(int i = s.length(); i > 0; i--) {

            if(s.subSequence(i-1, i).toString().equals("\n"))
                s.replace(i-1, i, "");
        }

        String myTextString = s.toString();
    }
});

Ответ 3


Свойство в XML

android:lines="5"
android:inputType="textPersonName"

Ответ 4

Это работает для меня:

<EditText
    android:inputType="textShortMessage|textMultiLine"
    android:minLines="3"
    ... />

Он отображает смайлик вместо клавиши Enter.

Ответ 5

Ответ, предоставленный @Andreas Rudolph, содержит критическую ошибку и не должен использоваться. Код вызывает IndexOutOfBoundsException, когда вы пропустили текст внутри EditText, который содержит несколько символов новой строки. Это вызвано типом используемого цикла, объект Editable вызывает метод afterTextChanged, как только его содержимое изменится (замените, удалите, вставьте).

Правильный код:

edittext.addTextChangedListener(new TextWatcher() {

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

    }

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

    }

    public void afterTextChanged(Editable s) {
        /*
         * The loop is in reverse for a purpose,
         * each replace or delete call on the Editable will cause
         * the afterTextChanged method to be called again.
         * Hence the return statement after the first removal.
         * http://developer.android.com/reference/android/text/TextWatcher.html#afterTextChanged(android.text.Editable)
         */
        for(int i = s.length()-1; i >= 0; i--){
            if(s.charAt(i) == '\n'){
                s.delete(i, i + 1);
                return;
            }
        }
    }
});

Ответ 6

Попробуйте следующее:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_ENTER)
    {
        //Nothing
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Ответ 7

Я тестирую это и, похоже, работает:

EditText editText = new EditText(context);
editText.setSingleLine(false);
editText.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT);

Ответ 8

Вы можете установить его из xml следующим образом:

android:imeOptions="actionDone"
android:inputType="text"
android:maxLines="10"

не забывайте android:inputType="text", если вы его не установили, он не работает. Однако я не знаю, почему. Также не забудьте изменить maxLines на ваше предпочтительное значение.

Ответ 9

Просто добавьте

        android:singleLine="true"

в ваш EditText

Ответ 10

Принятый ответ работал так хорошо, пока я не скопировал текст с разрывами строк в EditText. Поэтому я добавил onTextContextMenuItem для контроля действия вставки.

@Override
public boolean onTextContextMenuItem(int id) {
    boolean ret = super.onTextContextMenuItem(id);
    switch (id) {
        case android.R.id.paste:
            onTextPaste();
            break;
    }
    return ret;
}

public void onTextPaste() {
    if (getText() == null)
        return;
    String text = getText().toString();
    text = text.replaceAll(System.getProperty("line.separator"), " ");
    text = text.replaceAll("\\s+", " ");
    setText(text);
}

Ответ 11

Вот более правильный ответ, который не отображает клавишу ввода на клавиатуре IME:

// IMPORTANT, do this before any of the code following it
myEditText.setSingleLine(true);

// IMPORTANT, to allow wrapping
myEditText.setHorizontallyScrolling(false);
// IMPORTANT, or else your edit text would wrap but not expand to multiple lines
myEditText.setMaxLines(6);

Кроме того, вы можете заменить setSingleLine(true) либо на явный android:inputType в файле макета XML, либо на setInputType(InputType.*) На код, в котором используемый тип ввода - это все, что, как вы знаете, ограничивает ввод только одиночные строки (т.е. все, что вызывает неявно уже setSingleLine(true)).


Объяснение:

Что setSingleLine(true), так это setHorizontallyScrolling(true) вызов setHorizontallyScrolling(true) и setLines(1), а также изменение некоторых настроек клавиатуры IME для отключения клавиши ввода.

В свою очередь, вызов setLines(1) подобен вызову setMinLines(1) и setMaxLines(1) в одном вызове.

Некоторые типы ввода (т. InputType.TYPE_* Константы из InputType.TYPE_*) вызывают setSingleLine(true) неявно или, по крайней мере, достигают того же эффекта.

Заключение:

Таким образом, чтобы достичь того, что хочет OP, мы просто противостоим этим неявным настройкам, возвращая эти неявные вызовы.

Ответ 12

Добавление этого свойства в XML EditText для меня работает:

android:lines="1"

Он позволяет пользователям вводить символы новой строки, но сам EditText не увеличивается по высоте.

Ответ 13

Для URI вы можете использовать:

android:inputType="textUri"
android:lines="1"
android:maxLength="128"

В противном случае android:inputType="textPersonName", как упоминалось выше, работает для другого EditText, такого имени пользователя и т.д.

Ответ 14

<EditText 
  android:id="@+id/Msg"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"              
  android:layout_marginTop="5dip"
  android:lines="5"
  android:selectAllOnFocus="true"               
  android:hint="Skriv meddelande...\n(max 100tkn)"/>


EditText et = (EditText)findViewById(R.id.Msg);
String strTmp = et.getText().toString();
strTmp = strTmp.replaceAll("\\n"," ");

Ответ 15

    EditText textView = new EditText(activity);
    ...
    textView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
            if(KeyEvent.KEYCODE_ENTER == keyEvent.getKeyCode()) {
                return false;
            }
            ....... 

        }
    });

Ответ 16

Я дам другой вариант, чтобы вам не пришлось создавать подкласс EditText. Создайте InputFilter который отфильтровывает InputFilter. Затем используйте EditText.addInputFilter.

Исходный код для такого входного фильтра находится здесь: https://gist.github.com/CapnSpellcheck/7c72830e43927380daf5205100c93977

Вы можете передать 0 в конструкторе, и он не допустит никаких новых строк. Кроме того, вы можете комбинировать это с одним из других настроек, таких как android:imeOptions="actionDone", так как это поможет улучшить работу на некоторых устройствах.

Ответ 17

Вот решение....

<EditText
   android:id="@+id/editText"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:maxLength="150"                                 
   android:textSize="15dp"
   android:imeOptions="actionDone"
   android:inputType="text|textMultiLine"/>

Использование в классе Java

editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View view, int keyCode, KeyEvent event) {

            if (keyCode==KeyEvent.KEYCODE_ENTER)
            {
                // Just ignore the [Enter] key
                return true;
            }
            // Handle all other keys in the default way
            return (keyCode == KeyEvent.KEYCODE_ENTER);
        }
    });

Ответ 18

Вы можете изменить кнопку действия из кода

editText.imeOptions = EditorInfo.IME_ACTION_DONE
editText.setRawInputType(InputType.TYPE_CLASS_TEXT)

Xml

android:inputType="textMultiLine"