是否可以同时设置 android:inputType="textMultiLine"
和 android:imeOptions="actionDone"
属性来创建一个多行文本框,并让键盘上的操作按钮显示“完成”而不是“回车”(Enter)?
我想要一个多行编辑框,并希望键盘上的操作按钮是“完成”,而不是“回车”(Carriage Return),但似乎无法实现。
是否可以同时设置 android:inputType="textMultiLine"
和 android:imeOptions="actionDone"
属性来创建一个多行文本框,并让键盘上的操作按钮显示“完成”而不是“回车”(Enter)?
我想要一个多行编辑框,并希望键盘上的操作按钮是“完成”,而不是“回车”(Carriage Return),但似乎无法实现。
如果您在使用input选项textImeMultiline和imeoptions flagnext以及actionnext时,就会获得下一步按钮而不是回车符。
虽然其他解决方案对我都没有用,但是下面这个方案非常有效,让我省去了数天的搜索时间,当然还加入了我的一些变化。不幸的是,我不记得从哪里得到这段代码,因此无法给予作者应有的荣誉。
在你的Java代码中:
////////////Code to Hide SoftKeyboard on Enter (DONE) Press///////////////
editText.setRawInputType(InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD|InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeActionLabel("DONE",EditorInfo.IME_ACTION_DONE); //Set Return Carriage as "DONE"
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
if (event == null) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// Capture soft enters in a singleLine EditText that is the last EditText
// This one is useful for the new list case, when there are no existing ListItems
editText.clearFocus();
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}
else if (actionId == EditorInfo.IME_ACTION_NEXT) {
// Capture soft enters in other singleLine EditTexts
} else if (actionId == EditorInfo.IME_ACTION_GO) {
} else {
// Let the system handle all other null KeyEvents
return false;
}
}
else if (actionId == EditorInfo.IME_NULL) {
// Capture most soft enters in multi-line EditTexts and all hard enters;
// They supply a zero actionId and a valid keyEvent rather than
// a non-zero actionId and a null event like the previous cases.
if (event.getAction() == KeyEvent.ACTION_DOWN) {
// We capture the event when the key is first pressed.
} else {
// We consume the event when the key is released.
return true;
}
}
else {
// We let the system handle it when the listener is triggered by something that
// wasn't an enter.
return false;
}
return true;
}
});
我也曾经苦苦挣扎了很长时间,但最终我找到了解决方案!
只需创建一个自定义的EditText类,如下所示:
public class EditTextImeMultiline extends EditText {
public void init() {
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
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, "");
}
});
setSingleLine();
setHorizontallyScrolling(false);
this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
EditTextImeMultiline.this.setLines(EditTextImeMultiline.this.getLineCount());
}
});
}
public EditTextImeMultiline(Context context) {
super(context);
init();
}
public EditTextImeMultiline(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
}
这个类可以去除换行符(\n),像textMultiline一样包装文本,并允许您用ImeAction替换Enter按钮 ;).
您只需要在XML中调用它,而不是传统的EditText类。
这里的逻辑解释如下:
如果你使用DataBinding,你应该创建一个能捕捉操作的方法。参见https://dev59.com/1VcO5IYBdhLWcg3wvUMp#52902266。
一些扩展方法的文件,例如,BindingAdapters.kt:
@BindingAdapter("inputType", "action")
fun EditText.setMultiLineCapSentencesAndDoneAction(inputType: Int, callback: OnActionListener?) {
setRawInputType(inputType)
if (callback == null) setOnEditorActionListener(null)
else setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE ||
event?.keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN
) {
callback.enterPressed()
return@setOnEditorActionListener true
}
return@setOnEditorActionListener false
}
}
interface OnActionListener {
fun enterPressed()
}
然后在XML中:
<data>
<variable
name="viewModel"
type="YourViewModel" />
<import type="android.text.InputType" />
</data>
<EditText
android:imeOptions="actionDone"
android:inputType=""
app:action="@{() -> viewModel.send()}"
app:inputType="@{InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE}" />
对于 Compose UI,代码如下:
TextField(
...
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done
),
...
)
这里有一个可行的解决方案,创建自定义的EditTextView(只需扩展TextView),并重写onInputConnection方法,使用你会在这里找到的代码片段,该片段是被接受答案的链接:2.3上带有完成SoftInput操作标签的多行EditText