防止 EditText 上的 Enter 键,但仍将文本显示为多行

问题描述 投票:0回答:19

如何在Android上制作一个EditText,以便用户不能输入多行文本,但显示仍然是多行(即有自动换行而不是文本向右移动)?

类似于内置的短信应用程序,我们不能输入换行符,但文本会分行显示。

android android-edittext multiline
19个回答
49
投票

我将对该小部件进行子类化并覆盖按键事件处理,以阻止

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

49
投票

这是一种方法,您不必重写 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对早期答案的改进。


23
投票

XML 中的属性

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

14
投票

这个对我有用:

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

它显示笑脸而不是 Enter 键。


10
投票

这里有一个更正确的答案,在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 想要的效果,我们只需通过恢复这些隐式调用来对抗这些隐式设置。


8
投票

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

5
投票

我正在测试这个,它似乎有效:

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

5
投票

试试这个:

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

3
投票

您可以像这样从 xml 中设置它:

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

别忘了

android:inputType="text"
,不设置的话是不起作用的。我不知道为什么。 另外,不要忘记将
maxLines
更改为您的首选值。


3
投票

只需添加

        android:singleLine="true"

到你的EditText


2
投票

这是解决方案......

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

1
投票

接受的答案效果很好,直到我将带换行符的文本复制到 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);
}

1
投票

您可以从代码更改操作按钮

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

XML

android:inputType="textMultiLine"

0
投票
<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"," ");

0
投票
    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;
            }
            ....... 

        }
    });

0
投票

对于 URI,您可以使用:

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

否则

android:inputType="textPersonName"
如上所述适用于其他EditText,例如用户名等


0
投票

我将提供另一个选项,这样您就不必子类化 EditText。创建一个

InputFilter
来过滤掉换行符。然后使用
EditText.addInputFilter

此类输入过滤器的源代码位于:https://gist.github.com/CapnSpellcheck/7c72830e43927380daf5205100c93977

你可以在构造函数中传递 0,并且它不允许任何换行符。此外,您可以将此与其他调整之一结合起来,例如

android:imeOptions="actionDone"
,因为这将有助于改善某些设备上的体验。


0
投票
/**
 * 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
}

-1
投票

将此属性添加到

EditText
XML 对我有用:

android:lines="1"

它允许用户输入换行符,但

EditText
本身的高度不会增加。

© www.soinside.com 2019 - 2024. All rights reserved.