Запретить ввод ключа на EditText, но по-прежнему показывать текст как многострочный



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



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

652   17  

17 ответов:

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

Это метод, в котором вам не нужно переопределять класс 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();
    }
});

свойство в XML

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

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

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

Он показывает смайлик вместо ввода ключа.

ответ, предоставленный @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;
            }
        }
    }
});

Я тестирую это, и это, кажется, работает:

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

попробуйте это:

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

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

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

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

просто добавить

        android:singleLine="true"

к вашему EditText

принятый ответ работал так хорошо, пока я не скопировал текст со строчными разрывами в 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);
}

вот более правильный ответ, который не отображает клавишу enter на клавиатуре 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.*) on code – в котором используемый тип ввода-это все, что вы знаете, ограничивает ввод только одной строкой (т. е. все, что вызывает setSingleLine(true) уже неявно).


объяснение:

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

в свою очередь, вызов setLines(1) это как называть setMinLines(1) и setMaxLines(1) в один звонок.

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

вывод:

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

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

android:lines="1"

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

<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"," ");
    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;
            }
            ....... 

        }
    });

на URI вы могли бы использовать:

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

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

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

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

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

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

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

Comments

    Ничего не найдено.