是否可以EditText同时android:inputType="textMultiLine"设置一个小部件android:imeOptions="actionDone"?
我想要一个多行编辑框,将键盘上的操作按钮设置为“完成”,而不是Enter(回车),但是它似乎不起作用。
提前致谢
是否可以EditText同时android:inputType="textMultiLine"设置一个小部件android:imeOptions="actionDone"?
我想要一个多行编辑框,将键盘上的操作按钮设置为“完成”,而不是Enter(回车),但是它似乎不起作用。
提前致谢
Answers:
用
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
并使用XML:
android:inputType="textMultiLine"
textField.setCursorVisible(false);一个内部onEditorActionListener
来自android文档:' “ textMultiLine”普通文本键盘,允许用户输入长文本字符串,包括换行符(回车)。'因此,如果您想在键盘上使用“完成”按钮,则textMultiLine属性不合适。
使用完成按钮获取多行(在本例中为3行)输入字段的简单方法是将EditText与
android:lines="3"
android:scrollHorizontally="false"
但是,由于某种原因,这仅对我有效,如果我在代码中而不是在onCreate中通过布局文件(在onCreate中)进行了这些设置
TextView tv = (TextView)findViewById(R.id.editText);
if (tv != null) {
tv.setHorizontallyScrolling(false);
tv.setLines(3);
}
我希望这可以帮助某人,因为花了很长时间才弄清楚。如果您发现从清单中使之工作的方法,请告诉我们。
maxLines(),而不是setLines()如果你想避免改变的高度EditText
setMaxLines(3)),非常感谢!
工作实例!创建下面的支持此功能的自定义EditText类,并在xml文件中使用该类。工作代码:
package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;
public class ActionEditText extends EditText
{
public ActionEditText(Context context)
{
super(context);
}
public ActionEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ActionEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs)
{
InputConnection conn = super.onCreateInputConnection(outAttrs);
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
return conn;
}
}
<com.example.ActionEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textAutoCorrect|textCapSentences|textMultiLine" />
要在Kotlin中执行此操作(还可以选择应用其他配置,例如textCapSentences可以使用此扩展功能:
// To use this, do NOT set inputType on the EditText in the layout
fun EditText.setMultiLineCapSentencesAndDoneAction() {
imeOptions = EditorInfo.IME_ACTION_DONE
setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
}
用法:
myEditText.setMultiLineCapSentencesAndDoneAction()
setRawInputType代替setInputType
我认为这是做事情的方式。具有android:inputType="textMultiLine",android:imeOptions="actionDone"使输入键功能不明确。请记住,您可以使用android:lines="10",也可以删除android:inputType="textMultiLine",但是要取决于您要实现的目标,有时您只需要android:inputType="textMultiLine"并且没有替代品。
EditText ed=new EditText(this);
ed.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_ENTER){
//do your stuff here
}
return false;
}
});
在代码中设置这些值是唯一对我有用的东西
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) {
imeOptions = action
inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
setHorizontallyScrolling(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()
是否需要轻松控制回调中的键盘?阅读这篇文章
然后加入hideKeyboard()通话EditText.multilineDone
简短答案:不,我相信在API级别11(3.0)之前是不可能的。
这里出现了相同的问题(在对已接受答案的评论中进行了讨论):
从最后的评论:
查看我手机上的一些应用程序,最后一个多行框似乎很常见,在其下方有一个可见的“完成”或“发送”按钮(例如,电子邮件应用程序)。
解决这种情况的一种简单方法:
将此属性保留在EditText上:
android:inputType="textMultiLine"
android:scrollHorizontally="false"然后添加以下代码以仅在按下ENTER键时隐藏键盘:
editText.setOnEditorActionListener(new OnEditorActionListener()
{
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
{
editText.setSelection(0);
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
return true;
}
else
{
return false;
}
}
});尽管没有其他解决方案对我有用,但以下解决方案有效精美,救了我天或以上的谷歌搜索的天,我自己当然的一些曲折。不幸的是,我不记得我从哪里确切地获得了代码,因此不能给予作者应有的荣誉。
在您的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;
}
});
我在4.x上,尝试调用setHorizontallyScrolling()(带有或不带有setLine()或setMaxLines())以及许多不同的XML配置,以显示“完成”按钮。他们都没有工作。底线是,如果您的EditText是多行,Android将始终希望显示回车而不是“ Done”按钮,除非对此进行了一些修改。
我发现的最不复杂的解决方案不涉及重新映射回车的行为,请参见:https : //stackoverflow.com/a/12570003/3268329。此解决方案将消除Android的不屈不挠的愿望,即对多行视图强制设置IME_FLAG_NO_ENTER_ACTION标志,这会导致“完成”按钮消失。
我也挣扎了一段时间,但终于找到了解决方案!
只需创建一个自定义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();
}
}
此类删除lineBreaks(\ n),像textMultiline那样包装文本,并允许您用ImeAction;)替换Enter按钮。
您只需要在XML中而不是经典的EditText类中调用它即可。
在这里解释逻辑:
有效的解决方案在这里,创建您的自定义EditTextView(仅扩展文本视图)并重写onInputConnection,并在此处接受的答案中覆盖一段代码:在2.3上完成SoftInput Action Label的多行EditText