如何使用 ActionDone 按钮(没有 Enter 按钮)实现多行 EditText
How to implement Multiline EditText with ActionDone button (without Enter button)
我有 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_ACTION_DONE
的回调永远不会被调用。因此,每次用户按下该按钮时,光标都会移动到新行而不是发布消息。
如何保持 EditText 的多行行为(能够在多行上显示文本)和 ActionDone 按钮?
最后,在这里搜索类似的线程后,我找到了解决方案。只需在 Activity/Fragment:
中添加这些行
editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);
出于某种原因,如果您应用 xml 中的完全相同的设置,则它不起作用。您应该以编程方式进行。
还有另一种可能的解决方案 - 从 EditText 派生并手动应用 EditorInfo.IME_ACTION_DONE
。但对我来说,第一个解决方案看起来更简单。
继续 Ruslan 的回答。这个技巧奏效了,但在 XML 中还需要注意一件事。
EditText
应该有输入类型 text
否则 actionDone
将不起作用。 EditText
的默认输入类型允许用户输入换行符,因此 inputType 应设置为 text
即
android:inputType="text"
//And of course
android:imeOptions="actionDone"
并且在您的 java class 中您需要添加:
editText.setHorizontallyScrolling(false);
使用
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
在XML中:
android:inputType="textMultiLine"
来源:Multi-line EditText with Done action button
可重复使用的 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)
如果您想在 '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()
我有 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_ACTION_DONE
的回调永远不会被调用。因此,每次用户按下该按钮时,光标都会移动到新行而不是发布消息。
如何保持 EditText 的多行行为(能够在多行上显示文本)和 ActionDone 按钮?
最后,在这里搜索类似的线程后,我找到了解决方案。只需在 Activity/Fragment:
中添加这些行editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);
出于某种原因,如果您应用 xml 中的完全相同的设置,则它不起作用。您应该以编程方式进行。
还有另一种可能的解决方案 - 从 EditText 派生并手动应用 EditorInfo.IME_ACTION_DONE
。但对我来说,第一个解决方案看起来更简单。
继续 Ruslan 的回答。这个技巧奏效了,但在 XML 中还需要注意一件事。
EditText
应该有输入类型 text
否则 actionDone
将不起作用。 EditText
的默认输入类型允许用户输入换行符,因此 inputType 应设置为 text
即
android:inputType="text"
//And of course
android:imeOptions="actionDone"
并且在您的 java class 中您需要添加:
editText.setHorizontallyScrolling(false);
使用
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
在XML中:
android:inputType="textMultiLine"
来源:Multi-line EditText with Done action button
可重复使用的 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)
如果您想在 '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()