96

If I have an EditText and I want to listen for if the user presses the "done" button on the keypad.. how would I do this?

Gibolt
  • 42,564
  • 15
  • 187
  • 127
Skizit
  • 43,506
  • 91
  • 209
  • 269
  • 1
    Point to consider, the phone might have a physical keyboard, so the user might never press the done button on the keyboard, have you thought about doing your operation based on focus loss or editText editing end? – blindstuff Apr 15 '11 at 13:49
  • Possible duplicate: https://stackoverflow.com/a/60989441/878126 – android developer Apr 02 '20 at 10:28

7 Answers7

166

Dinash answer is nice, but it is not working on all devices. Below code works fine for all devices

edittext.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
            return true;
        }
        return false;
    }
});
Asad Rao
  • 3,190
  • 1
  • 22
  • 26
102

Code is

final EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setOnKeyListener(new View.OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
            Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
            return true;
        }
        return false;
    }
});

In that 'edittext' is id of textfield

Check out this link Simply set setOnKeyListener to your editText

Westy92
  • 19,087
  • 4
  • 72
  • 54
Dinash
  • 3,027
  • 4
  • 32
  • 45
  • 6
    Hi Dinash. Just posting a link generally isn't helpful. It's better to provide some sample code which answers the askers question and then link to the source article as reference or for further reading. – Chris Salij Apr 16 '11 at 09:48
  • Hi Chris i though you can find the answer from that link itself but still i give an exact working code available in the link itself... Code is final EditText edittext = (EditText) findViewById(R.id.edittext); edittext.setOnKeyListener(new OnKeyListener() {public boolean onKey(View v, int keyCode, KeyEvent event) {if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show(); return true;}return false;}}); Hope you can find it helpful... In that 'edittext' is id of textfield – Dinash Apr 18 '11 at 07:34
  • It will not work on custom keyboard. setOnKeyListener will not be called on some custom keyboards. – Abeer Iqbal Jan 24 '19 at 13:15
  • It does not work for some of my devices or keyboard software. – Chanh Oct 04 '19 at 09:33
  • "event.getAction() == KeyEvent.ACTION_DOWN" is deprecated – Majid Sadeghi May 11 '20 at 11:47
  • Does not work on Samsung S20 – Rowan Berry Jun 09 '20 at 05:15
24

Kotlin Extension Solution

The base way to handle the done action in Kotlin is:

edittext.setOnEditorActionListener { _, actionId, _ ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        // Call onDone result here
        true
    }
    false
}

Kotlin Extension

Use this to call edittext.onDone {/*action*/} in your main code. Keeps it more readable and maintainable

edittext.onDone { submitForm() }

fun EditText.onDone(callback: () -> Unit) {
    // These lines optional if you don't want to set in Xml
    imeOptions = EditorInfo.IME_ACTION_DONE
    maxLines = 1
    setOnEditorActionListener { _, actionId, _ ->
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            callback.invoke()
            true
        }
        false
    }
}

Don't forget to add these options to your edittext Xml, if not in code

<EditText ...
    android:imeOptions="actionDone"
    android:inputType="text"/>

If you need inputType="textMultiLine" support, read this post

Gibolt
  • 42,564
  • 15
  • 187
  • 127
  • Just as a note to everyone, android:imeOptions="actionDone" does not perform uniformly across all devices, I have explicitly avoided it as much as possible as older devices with working key listeners begin to ignore them when this is active. I also find it can tab you to weird places, it also was picking up the backspace key on the Samsung S20 – Rowan Berry Jun 09 '20 at 05:24
  • 2
    You should add explicit return@setOnEditorActionListener cuz "if" isn't last statement – CeH9 Jan 18 '21 at 16:25
9

The same Jone answer, but with replaced lambda:

etPointCombatFirst.setOnEditorActionListener((v, actionId, event) -> {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
                    return true;
                }
                return false;
            });
Serg Burlaka
  • 2,351
  • 24
  • 35
7

Based on the response of Asad Rao, I created this KOTLIN extension function.

fun TextView.onClickKeyboardDoneButton(funExecute: () -> Unit) {
    this.setOnEditorActionListener { _, actionId, _ ->
        when (actionId) {
            EditorInfo.IME_ACTION_DONE -> {
                funExecute.invoke()
                true
            }
            else -> false
        }
    }
}

Use:

myEditText.onClickKeyboardDoneButton{myFunctionToExecuteWhenUserClickDone()}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Emmanuelguther
  • 1,039
  • 4
  • 19
  • 29
2

Rx way to do this:

fun EditText.onImeActionDoneClicks(): Observable<Unit> {
    return Observable.create { emitter ->
        setOnEditorActionListener { _, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                emitter.onNext(Unit)
                true
            } else {
                false
            }
        }
    }
}

compositeDisposable += lastEditText.onImeActionDoneClicks().subscribe {
    toast("onImeDoneClicks")
}
Weiyi
  • 1,843
  • 2
  • 22
  • 34
2

This Kotlin version should work on all devices:

editText.setOnEditorActionListener { _, actionId, _ ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        // Do something
        true
    } else {
        false
    }
}
Westy92
  • 19,087
  • 4
  • 72
  • 54