Как сделать 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"