Android 如何使用ActionDone按钮(无Enter按钮)实现多行EditText

Android 如何使用ActionDone按钮(无Enter按钮)实现多行EditText,android,android-edittext,multiline,ime,imeoptions,Android,Android Edittext,Multiline,Ime,Imeoptions,我有EditText,用于输入消息(电子邮件、短信)的内容。我希望消息立即发布在ActionDone按钮上。为此,我使用以下代码: message.setOnEditorActionListener((textView, i, keyEvent) -> { switch (i) { case EditorInfo.IME_ACTION_DONE: if (messageCanBePosted()

我有EditText,用于输入消息(电子邮件、短信)的内容。我希望消息立即发布在ActionDone按钮上。为此,我使用以下代码:

message.setOnEditorActionListener((textView, i, keyEvent) -> {
            switch (i) {
                case EditorInfo.IME_ACTION_DONE:
                    if (messageCanBePosted()) {
                        SoftKeyboard.hide(message);
                        postMessage();
                        return true;
                    } else {
                        return false;
                    }
                default:
                    return false;
            }
        }); 
但我也希望这个消息字段是多行的,就像在任何其他messenger应用程序中一样。我可以通过以下方式实现:

android:inputType="textMultiLine"
问题是,添加这一行后,ActionDone按钮开始像Enter按钮一样工作。因此,我用于捕获
EditorInfo.IME\u ACTION\u DONE
的回调从未被调用。所以,每次用户按下该按钮时,光标移动到新行,而不是发布消息


如何保持EditText的多行行为(能够在多行上显示文本)和ActionDone按钮?

最后,在这里搜索类似的线程后,我找到了解决方案。只需在活动/片段上添加以下行:

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);
出于某种原因,如果从xml中应用完全相同的设置,它将不起作用。你应该以编程的方式来做

还有另一种可能的解决方案-从EditText派生并手动应用
EditorInfo.IME\u ACTION\u DONE
。但对我来说,第一个解决方案看起来更简单。

继续Ruslan的答案。这个技巧奏效了,但在XML中还有一件事需要注意

EditText
应具有输入类型
text
,否则
actionDone
将不起作用。
EditText
的默认输入类型允许用户输入换行符,因此应将inputType设置为
text
,即

android:inputType="text"
//And of course
android:imeOptions="actionDone"
在java类中,您需要添加:

editText.setHorizontallyScrolling(false);
使用

和XML格式:

android:inputType="textMultiLine"
来源:

可重复使用的Kotlin解决方案 多亏了其他答案,在代码中设置这些值对我来说非常有效

edittext.inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
edittext.setHorizontallyScrolling(false)
edittext.maxLines = Integer.MAX_VALUE // Or your preferred fixed value
我经常需要这样做,因此为了保持代码的整洁,我做了以下几点:

fun EditText.multilineIme(action: Int) {
    inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
    horizontalScroll(false)
    maxLines = Integer.MAX_VALUE
}

// Then just call
edittext.multilineIme(EditorInfo.IME_ACTION_DONE)
如果要在“完成”上添加可选自定义操作,请尝试以下操作:

fun EditText.multilineDone(callback: (() -> Unit) = null) {
    val action = EditorInfo.IME_ACTION_DONE
    multilineIme(action)
    setOnEditorActionListener { _, actionId, _ ->
            if (action == actionId) {
                callback?.invoke()
                true
            }
            false
        }
    }
}

// Then you can call
edittext.multilineDone { closeKeyboard() }

// or just
edittext.multilineDone()

@silverFox是的,这对我很有效。您在xml中为EditText定义了哪些属性?非常棒。我已经试着这么做了好几天,觉得这是不可能的。谢谢最后从EditText派生并手动应用导致EditText行为怪异(失去焦点忽略设置文本..魔术…)这个简单的解决方案效果很好。这个答案+EditText.setRawInputType(InputType.TYPE_CLASS_text)对我有效。。在具体的例子中,我还使用了xml中的digits字段()只有这一个对我有效,它像一个符咒一样工作-显示完成按钮&工作,当EditText最初为空时,只有一行可见,当用户键入或最初从代码中添加更多文本时,扩展到更多行(setText)引用源代码会很好:谢谢,在搜索了几个小时后,你是对的,它不仅仅通过更改xml起作用。真是一团糟……终于成功了!这对我来说太神奇了,多年来,xml EditText属性中出现了这个可怕的错误!对于多行URL文本输入字段,这是对我有效的:
editText.setRawInputType(InputType.TYPE_CLASS_text | InputType.TYPE_text_VARIATION_URI);editText.setImeOptions(EditorInfo.IME\u ACTION\u DONE)并且不需要在EditText XML属性中指定任何内容。一些键盘通过显示网址建议或显示“.com”键来适应这种输入类型。输入类型=text&imeOptions=actionDone在xml中,代码中的setHorizontallyScrolling()完成了!最后谢谢你。
fun EditText.multilineDone(callback: (() -> Unit) = null) {
    val action = EditorInfo.IME_ACTION_DONE
    multilineIme(action)
    setOnEditorActionListener { _, actionId, _ ->
            if (action == actionId) {
                callback?.invoke()
                true
            }
            false
        }
    }
}

// Then you can call
edittext.multilineDone { closeKeyboard() }

// or just
edittext.multilineDone()