android – How to implement Multiline EditText with ActionDone button (without Enter button)-ThrowExceptions

Exception or error:

I have EditText which is used for entering contents on messages (emails, sms). I want message to be immediately posted on ActionDone button click. I use following code for this:

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

But also I want this message field to be multiline, like in any other messenger apps. I can achieve it with this line:

android:inputType="textMultiLine"

The problem is that after adding this line ActionDone button starts acting like Enter button. So my callback for catching EditorInfo.IME_ACTION_DONE is never called. So each time user press that button cursor moves to new line instead of posting message.

How can I keep both multiline behavior of EditText (ability to show text on multiple lines) and ActionDone button?

How to solve:

Use

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

and in XML:

android:inputType="textMultiLine"

Source : Multi-line EditText with Done action button

###

Finally, after searching here for similar threads I have found solution. Just need to add these lines on your Activity/Fragment:

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

For some reason it doesn’t work if you apply exact same setting from xml. You should do it programmatically.

There is also another possible solution – derive from EditText and apply EditorInfo.IME_ACTION_DONE manually. But for me first solution looks simpler.

###

Continuing Ruslan‘s answer. The trick worked but there is one more thing that you need to take care of in XML.

EditText should have input type text otherwise actionDone won’t work. Default input type of EditText does allow user to input line breaks so inputType should be set to text i.e.

android:inputType="text"
//And of course
android:imeOptions="actionDone"

And in your java class you need to add:

editText.setHorizontallyScrolling(false);

###

Reuseable Kotlin Solution

Setting these values in code worked for me, thanks to the other answers

edittext.inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
edittext.setHorizontallyScrolling(false)
edittext.maxLines = Integer.MAX_VALUE // Or your preferred fixed value

I require this frequently, so made this to keep the code clean:

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)

If you want to be add an optional custom action on ‘Done’, try this:

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

Leave a Reply

Your email address will not be published. Required fields are marked *