带有“完成”操作button的多行EditText

是否有可能与android:inputType="textMultiLine"设置,和android:imeOptions="actionDone"在同一时间的EditText小部件?

我想要一个多行编辑框,键盘上的动作button是完成,而不是input(回车),但它似乎并没有工作..

提前致谢

从android文档: “textMultiLine”普通文本键盘,允许用户input包含换行符(回车)的长文本string。 因此,如果你想在键盘上有“完成”button,textMultiLine属性是不合适的。

一个简单的方法来得到一个多行(在这种情况下,3行)input字段与完成button是使用EditText与

 android:lines="3" android:scrollHorizontally="false" 

但是,出于某种原因,这只适用于我,如果我在代码而不是布局文件(在onCreate)这些设置通过

 TextView tv = (TextView)findViewById(R.id.editText); if (tv != null) { tv.setHorizontallyScrolling(false); tv.setLines(3); } 

我希望这有助于某人,因为花了相当长的一段时间才弄清楚。 如果您find一种方法,使其从清单工作,请让我们知道。

使用

 editText.setImeOptions(EditorInfo.IME_ACTION_DONE); editText.setRawInputType(InputType.TYPE_CLASS_TEXT); 

和XML:

 android:inputType="textMultiLine" 

工作示例! 创build支持此function的下面的自定义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" /> 

我认为这是你做事情的方式。 有android:inputType="textMultiLine"android:imeOptions="actionDone"使input键function不明确。 只要记住,你可以使用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==66){ //do your stuff here } return false; } }); 

简短的回答:不,我相信在API级别11(3.0)之前是不可能的。

同样的问题在这里出现(在接受的答案的评论中讨论):

Android软键盘操作button

从最后的评论:

在我的手机上查看几个应用程序,多线盒看起来很常见,在它下面有一个可见的“完成”或“发送”button(例如,电子邮件应用程序)。

如果不是屏幕键盘的外观,只需在键盘上放置一个input监听器,并在用户input换行符时触发“完成”状态。

如果您使用input选项textImeMultiline与imeoptions旗下和actionnext你得到下一个button,而不是cariage返回

我在4.x上,并尝试调用setHorizo​​ntalScrolling()(带或不带setLine()或setMaxLines()),以及许多不同的XMLconfiguration,以显示完成button。 他们都没有工作。 底线是,如果你的EditText是多行的,Android总是希望显示回车符,而不是“完成”button,除非你在这里附加一些黑客。

我发现最less的复杂解决scheme不涉及重新映射回车的行为在这里: https : //stackoverflow.com/a/12570003/3268329 。 这个解决scheme将使Android无情地迫使设置多行视图的IME_FLAG_NO_ENTER_ACTION标志,导致完成button消失。

一个简单的方法来解决这种情况:

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

我奋斗了很长一段时间,但我终于find了解决scheme!

只要创build一个自定义的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,并允许用ImeActionreplaceEnterbutton;)。

你只需要在你的XML而不是经典的EditText类中调用它。

为了解释这里的逻辑:

  • 将EditText设置为单行,以便能够显示ImeActionbutton而不是Enter。
  • 去除水平滚动以使文本在到达视图的末尾时转到下一行。
  • 使用onGlobalLayoutListener监视布局更改,并将其“line”参数设置为editText保存的当前文本的“lineCount”。 这是什么刷新其高度。

工作的解决scheme是在这里,创build您的自定义EditTextView(只是扩展一个文本视图),并覆盖onInputConnection一个代码片段,你会发现在接受的答案在这里: Multiline EditText与完成SoftInput行动标签2.3

虽然没有其他的解决scheme曾经为我工作,下面的工作很好,并保存我更多的使用googlesearch的天和几天,当然有一些我自己的曲折。 不幸的是,不记得我从哪里得到的代码,所以不能给作者他/她应得的功劳。

在你的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; } }); 

这似乎对我来说是完美的

 int lineNum = 2; mEditText.setHorizontallyScrolling(false); mEditText.setLines(3); 

一个简单的方法来解决这种情况:

更改EditText上的属性:

 android:inputType="textMultiLine" android:scrollHorizontally="false" 

至:

 android:inputType="textImeMultiLine" android:scrollHorizontally="false"