148

Ok in my app I have a field for the user to input a number. I have the field set to only accept numbers. When the user clicks on the field it brings up the keyboard. On the keyboard (on ICS) there is a done button. I would like for the done button on the keyboard to trigger the submit button i have in my application. My code is as follows.

package com.michaelpeerman.probability;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.Random;

public class ProbabilityActivity extends Activity implements OnClickListener {

private Button submit;
ProgressDialog dialog;
int increment;
Thread background;
int heads = 0;
int tails = 0;

public void onCreate(Bundle paramBundle) {
    super.onCreate(paramBundle);
    setContentView(R.layout.main);
    submit = ((Button) findViewById(R.id.submit));
    submit.setOnClickListener(this);
}

public void onClick(View view) {
    increment = 1;
    dialog = new ProgressDialog(this);
    dialog.setCancelable(true);
    dialog.setMessage("Flipping Coin...");
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    dialog.setProgress(0);
    EditText max = (EditText) findViewById(R.id.number);
    int maximum = Integer.parseInt(max.getText().toString());
    dialog.setMax(maximum);
    dialog.show();
    dialog.setOnCancelListener(new OnCancelListener(){

          public void onCancel(DialogInterface dialog) {

              background.interrupt();
              TextView result = (TextView) findViewById(R.id.result);
                result.setText("heads : " + heads + "\ntails : " + tails);


          }});


    background = new Thread(new Runnable() {
        public void run() {
            heads=0;
            tails=0;
            for (int j = 0; !Thread.interrupted() && j < dialog.getMax(); j++) {
                int i = 1 + new Random().nextInt(2);
                if (i == 1)
                    heads++;
                if (i == 2)
                    tails++;
                progressHandler.sendMessage(progressHandler.obtainMessage());
            }
        }
    });
    background.start();
}

Handler progressHandler = new Handler() {
    public void handleMessage(Message msg) {

        dialog.incrementProgressBy(increment);
        if (dialog.getProgress() == dialog.getMax()) {
            dialog.dismiss();
            TextView result = (TextView) findViewById(R.id.result);
            result.setText("heads : " + heads + "\ntails : " + tails);


        }
    }

};

}
mpeerman
  • 2,050
  • 2
  • 16
  • 16
  • 1
    check this http://stackoverflow.com/questions/5330243/how-to-catch-a-soft-keyboard-enter-done-press – Nishant Mar 07 '12 at 04:55
  • That refers to the textbox updating. – mpeerman Mar 07 '12 at 05:03
  • What i want to do is for it too trigger a button i already have. I dont want to get rid of the button because some people may be using keyboards that dont have a done button. – mpeerman Mar 07 '12 at 05:03
  • possible duplicate of [Android detect Done key press for OnScreen Keyboard](http://stackoverflow.com/questions/5077425/android-detect-done-key-press-for-onscreen-keyboard) – Elltz Apr 15 '15 at 18:31

13 Answers13

343

You can use this one also (sets a special listener to be called when an action is performed on the EditText), it works both for DONE and RETURN:

max.setOnEditorActionListener(new OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
                Log.i(TAG,"Enter pressed");
            }    
            return false;
        }
    });

Also, showing a nice send button in the keyboard itself would make it better. Add below line in EditText xml:

android:imeOptions="actionSend"
android:inputType="text"
Prajwal Waingankar
  • 2,534
  • 2
  • 13
  • 20
vladexologija
  • 6,857
  • 4
  • 29
  • 28
  • 1
    How can i set it to trigger the on click i already have running off of the submit button public void onClick(View view) { – mpeerman Mar 07 '12 at 15:19
  • 3
    You can either move all that code into single function and then call it or use [performClick()](http://developer.android.com/reference/android/view/View.html#performClick%28%29) – vladexologija Mar 08 '12 at 10:07
  • 6
    This did not work for me when hitting a DONE button, the KeyEvent was always null.. the actionId however was set to EditorInfo.IME_ACTION_DONE and I was able to use that instead. (This is in android 4.2.2 and does not even match the android sdk documentation at this time) – James May 01 '14 at 01:20
30

You can try with IME_ACTION_DONE .

This action performs a “done” operation for nothing to input and the IME will be closed.

 Your_EditTextObj.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                  /* Write your logic here that will be executed when user taps next button */


                    handled = true;
                }
                return handled;
            }
        });
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
29

Kotlin Solution

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

edittext.setOnEditorActionListener { _, actionId, _ ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        // Call your code 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) {
    setOnEditorActionListener { _, actionId, _ ->
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            callback.invoke()
            true
        }
        false
    }
}

Don't forget to add these options to your edittext

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

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

Gibolt
  • 42,564
  • 15
  • 187
  • 127
  • This listener in fact always returns `false` (Kotlin puzzler ;)), but it is fine: we typically want keyboard to close. – gmk57 May 20 '21 at 15:41
  • @gmk57 Try adding an else to that if statement and have it contain the false. I believe you are always seeing false because the if statement sets a true, but then it flows directly to the false on the next line (outside the if). – jj. Jul 21 '21 at 02:58
17

Try this:

max.setOnKeyListener(new OnKeyListener(){
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event){
        if(keyCode == event.KEYCODE_ENTER){
            //do what you want
        }
    }
});
TooCool
  • 10,598
  • 15
  • 60
  • 85
Roman Black
  • 3,501
  • 1
  • 22
  • 31
8

Try this for Xamarin.Android (Cross Platform)

edittext.EditorAction += (object sender, TextView.EditorActionEventArgs e) {
       if (e.ActionId.Equals (global::Android.Views.InputMethods.ImeAction.Done)) {
           //TODO Something
       }
};
Engr Waseem Arain
  • 1,163
  • 1
  • 17
  • 36
Nitin V. Patil
  • 185
  • 2
  • 2
4

I copied the following code from AndroidStudio when you create a LoginActivity. I use the ime attributes

In your layout

<EditText android:id="@+id/unidades" android:layout_width="match_parent"
                    android:layout_height="wrap_content" android:hint="@string/prompt_unidades"
                    android:inputType="number" android:maxLines="1"
                    android:singleLine="true"
                    android:textAppearance="?android:textAppearanceSmall"
                    android:enabled="true" android:focusable="true"
                    android:gravity="right"
                    android:imeActionId="@+id/cantidad"
                    android:imeActionLabel="@string/add"
                    android:imeOptions="actionUnspecified"/>

In your Activity

editTextUnidades.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == R.id.cantidad || actionId == EditorInfo.IME_NULL) {
                addDetalle(null);
                return true;
            }
            return false;
        }
    });
Juan Rojas
  • 8,711
  • 1
  • 22
  • 30
2

You can implement on key listener:

public class ProbabilityActivity extends Activity implements OnClickListener, View.OnKeyListener {

In onCreate:

max.setOnKeyListener(this);

...

@Override
public boolean onKey(View v, int keyCode, KeyEvent event){
    if(keyCode == event.KEYCODE_ENTER){
        //call your button method here
    }
    return true;
}
TinMan
  • 99
  • 2
  • 13
1

if you want to catch the keyboard enter button for doing your job which you want to done through any event like button click, you can write the below simple code for that text view

Edittext ed= (EditText) findViewById(R.id.edit_text);

ed.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        // Do you job here which you want to done through event
    }
    return false;
}
});
Nadeem Bhat
  • 1,032
  • 7
  • 10
1

Kotlin and Numeric keyboard

If you are using the numeric keyboard you have to dismiss the keyboard, it will be like:

editText.setOnEditorActionListener { v, actionId, event ->
  if (action == EditorInfo.IME_ACTION_DONE || action == EditorInfo.IME_ACTION_NEXT || action == EditorInfo.IME_ACTION_UNSPECIFIED) {
      //hide the keyboard
      val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
      imm.hideSoftInputFromWindow(windowToken, 0)
      //Take action
      editValue.clearFocus()
      return true
  } else {
      return false
  }
}
0

Use this class in your layout :

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

}

In xml:

<com.test.custom.ActionEditText
                android:id="@+id/postED"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:gravity="top|left"
                android:hint="@string/msg_type_message_here"
                android:imeOptions="actionSend"
                android:inputType="textMultiLine"
                android:maxLines="5"
                android:padding="5dip"
                android:scrollbarAlwaysDrawVerticalTrack="true"
                android:textColor="@color/white"
                android:textSize="20sp" />
Yogendra
  • 4,817
  • 1
  • 28
  • 21
0
max.setOnKeyListener(new OnKeyListener(){
  @Override
  public boolean onKey(View v, int keyCode, KeyEvent event){
    if(keyCode == event.KEYCODE_ENTER){
        //do what you want
    }
  }
});
Alexander
  • 2,925
  • 3
  • 33
  • 36
RkKhanpuriya
  • 164
  • 1
  • 13
  • 1
    Commenting on your code always improves the readability of an answer... – jAC Jun 21 '17 at 18:46
  • While this code may answer the question, providing additional [context](https://meta.stackexchange.com/q/114762) regarding how and/or why it solves the problem would improve the answer's long-term value. Remember that you are answering the question for readers in the future, not just the person asking now! Please [edit] your answer to add an explanation, and give an indication of what limitations and assumptions apply. It also doesn't hurt to mention why this answer is more appropriate than others. – Dev-iL Jun 22 '17 at 06:33
0

Your Last Edittext .setOnEditorActionListener call this method automatic hit api

I was Call in LoginActivity in et_password

 et_Pass.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {

                    Log.i(TAG,"Enter pressed");
                    Log.i(Check Internet," and Connect To Server");

                }
                return false;
            }
        });

Working Fine

Keshav Gera
  • 10,807
  • 1
  • 75
  • 53
0

And this is a Kotlin version:

editText.setOnEditorActionListener { v, actionId, event ->
  if(actionId == EditorInfo.IME_ACTION_DONE){
      //Put your action there
      true
  } else {
      false
  }
}
iluxa.b
  • 375
  • 1
  • 6
  • 16