如何在Android上制作一个EditText,以便用户不能输入多行文本,但显示仍然是多行(即有自动换行而不是文本向右移动)?
类似于内置的短信应用程序,我们不能输入换行符,但文本会分行显示。
我将对该小部件进行子类化并覆盖按键事件处理,以阻止
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);
}
}
这是一种方法,您不必重写 EditText 类。您只需捕获换行符并将其替换为空字符串即可。
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;
}
}
}
});
感谢Rolf对早期答案的改进。
XML 中的属性
android:lines="5"
android:inputType="textPersonName"
这个对我有用:
<EditText
android:inputType="textShortMessage|textMultiLine"
android:minLines="3"
... />
它显示笑脸而不是 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)
替换为 XML 布局文件上的显式 android:inputType
或代码上的 setInputType(InputType.*)
- 其中使用的输入类型是您知道的将输入限制为仅单行的任何类型(即任何已经隐式调用 setSingleLine(true)
的内容)。
说明:
setSingleLine(true)
的作用是隐式调用 setHorizontallyScrolling(true)
和 setLines(1)
,同时更改一些 IME 键盘设置以禁用 Enter 键。
反过来,调用
setLines(1)
就像一次调用 setMinLines(1)
和 setMaxLines(1)
。
某些输入类型(即
InputType.TYPE_*
中的常量)隐式调用setSingleLine(true)
,或者至少达到相同的效果。
结论:
因此,为了实现 OP 想要的效果,我们只需通过恢复这些隐式调用来对抗这些隐式设置。
@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
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);
}
});
接受的答案效果很好,直到我将带换行符的文本复制到 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);
}
您可以从代码更改操作按钮
editText.imeOptions = EditorInfo.IME_ACTION_DONE
editText.setRawInputType(InputType.TYPE_CLASS_TEXT)
XML
android:inputType="textMultiLine"
<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"
,因为这将有助于改善某些设备上的体验。
/**
* Set the EditText to multiline
* Starting with one line and expanding to maxLines = line
* the next action will be force to IME_ACTION_NEXT
*/
fun TextInputEditText.setMultilineTextNextAction(lines: Int) {
imeOptions = EditorInfo.IME_ACTION_NEXT
setRawInputType(InputType.TYPE_CLASS_TEXT)
maxLines=lines
}
将此属性添加到
EditText
XML 对我有用:
android:lines="1"
它允许用户输入换行符,但
EditText
本身的高度不会增加。