Multiline EditText with Finish Button

Is it possible to have an EditText widget with android:inputType="textMultiLine" and android:imeOptions="actionDone" at the same time?

I need a multi-line edit window, while the action button on the keyboard will be executed, not Enter (carriage return), but it does not seem to work.

Thank you in advance

+83
android
Jun 06 2018-10-06T00:
source share
16 answers

Use

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

and in XML:

 android:inputType="textMultiLine" 
+126
Dec 07 '16 at 16:30
source share

From the android documentation: '"textMultiLine" A plain text keyboard that allows users to enter long lines of text containing line breaks (carriage return) . 'Therefore, the textMultiLine attribute is not suitable if you want to have a “Finish” button on your keyboard.

An easy way to get a multi-line (in this case 3 lines) input field using a button made is to use EditText with

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

However, for some reason this only works for me if I make these settings in the code instead of the layout file (in onCreate) on

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

I hope this helps someone, as it took quite a while to figure it out. If you find a way to make it work from the manifest, let us know.

+48
Jun 10 '13 at 22:01
source share

Working example! Create the following custom EditText class that supports this function and use the class in the XML file. Work code:

 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" /> 
+22
Oct 19 '15 at 5:53 on
source share

I think this is a way to do what you need. Having android:inputType="textMultiLine" , android:imeOptions="actionDone" makes android:imeOptions="actionDone" the key input functionality. Just keep in mind that you can use android:lines="10" and possibly remove android:inputType="textMultiLine" , but it depends on what you want to achieve, sometimes you just need android:inputType="textMultiLine" and there is no substitute for this.

 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; } }); 
+6
Jul 21 2018-11-11T00:
source share

This seems to work great for me.

 int lineNum = 2; mEditText.setHorizontallyScrolling(false); mEditText.setLines(3); 
+5
Apr 16 '17 at 10:54 on
source share

Short answer: No, I think this is not possible up to API level 11 (3.0).

The same problem arose here (discussed in the comments on the accepted answer):

Android soft button for keyboard

From the final comment:

If you look at several applications on my phone, it seems that there is a multi-line block for this with the visible message “Finish” or “Send” (for example, an email application).

+3
Jun 08 '11 at 18:16
source share

If this is not about the appearance of the on-screen keyboard, you can simply add a listener to the keyboard and run the "done" -status if the user enters a new line.

+2
Apr 28 2018-11-21T00:
source share

if you use the textImeMultiline input parameter using imeoptions flagnext and actionnext, you get the following button instead of returning caries

+2
Jun 23 '13 at 20:25
source share

I'm on 4.x and tried calling setHorizontallyScrolling () (with or without setLine () or setMaxLines ()), as well as many different XML configurations to show the Finish button. None of them worked. The bottom line is that if your EditText is multi-line, Android will always want to show a carriage return instead of the Finish button if you don’t put any hack into it.

The smallest solution for complications I have found does not include reassigning carriage return behavior: https://stackoverflow.com/a/212632/ This decision invalidates Android’s unwanted desire to force the IME_FLAG_NO_ENTER_ACTION flag for multi-line views, which causes the Finish button to disappear.

+1
03 Feb
source share

A simple way to get around this situation:

  • save these attributes in EditText:

     android:inputType="textMultiLine" android:scrollHorizontally="false" 
  • then add this code to hide the keyboard only when ENTER is pressed:

     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; } } }); 
+1
Apr 01 '15 at 18:28
source share

I fought too long, but finally found a solution!

Just create your own EditText class as such:

 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(); } } 

This class removes lineBreaks (\ n), wraps the text like textMultiline, and allows you to replace the Enter button with ImeAction;).

You just need to call it in XML instead of the classic EditText class.

To explain the logic here:

  • Set EditText as a singleLine to show the ImeAction button instead of Enter.
  • Delete the horizontal scroll so that the text moves to the next line when it reaches the end of the view.
  • View layout changes with onGlobalLayoutListener and set the line parameter to lineCount of the current text stored in the editText file. This is what refreshes its height.
0
Jan 13 '16 at 13:45
source share

The working solution is here, create your own EditTextView (just expand the text view) and redefine onInputConnection with the part of the code that you will find in the accepted answer here: Multiline EditText with Done SoftInput Action Label on 2.3

0
Feb 05 '16 at 15:36
source share

Despite the fact that none of the other solutions for me ever worked, it worked beautifully and saved me from several days and days from searching on Google, of course, with a few twists. Unfortunately, I don’t remember where I got the code from, and therefore I can’t give the author the credit that he deserves.

In Java code:

 ////////////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; } }); 
0
Feb 14 '17 at 21:18
source share

An example of a Kotlin extension function to include a Done action and a specific combination of input types in EditTextExt.kt:

 // To use this, do NOT set inputType on the EditText in the XML layout fun EditText.setMultiLineCapSentencesAndDoneAction() { imeOptions = EditorInfo.IME_ACTION_DONE setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or InputType.TYPE_TEXT_FLAG_MULTI_LINE) } 

Then use:

 myEditText.setMultiLineCapSentencesAndDoneAction() 
0
Oct. 15 '18 at 10:27
source share

To do this in Kotlin (and also possibly apply other configurations such as textCapSentences you can use this extension function:

 // 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) } 

Using:

 myEditText.setMultiLineCapSentencesAndDoneAction() 
0
Dec 04 '18 at 13:27
source share

A simple way to get around this situation:

change attributes in EditText:

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

at

 android:inputType="textImeMultiLine" android:scrollHorizontally="false" 
-one
Dec 07 '16 at 13:07 on
source share



All Articles