Android – Maneje “Enter” en un EditText

Me pregunto si hay una forma de manejar al usuario presionando Enter mientras EditText un EditText , algo así como el evento onSubmit HTML.

También se pregunta si hay una forma de manipular el teclado virtual de tal manera que el botón “Listo” esté etiquetado de otra manera (por ejemplo, “Ir”) y realice una determinada acción al hacer clic (de nuevo, como en Enviar).

Me pregunto si hay una forma de manejar al usuario presionando Enter mientras tipea un EditText, algo así como el evento onSubmit HTML.

Sí.

También se pregunta si hay una forma de manipular el teclado virtual de tal manera que el botón “Listo” esté etiquetado de otra manera (por ejemplo, “Ir”) y realice una determinada acción al hacer clic (de nuevo, como en Enviar).

También sí

Deberá mirar los android:imeActionId y android:imeOptions , más el método setOnEditorActionListener() , todo en TextView .

Para cambiar el texto del botón “Hecho” por una cadena personalizada, use:

 mEditText.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER); 

Esto es lo que haces. También está oculto en el código de muestra del desarrollador de Android ‘Bluetooth Chat’. Reemplace las partes en negrita que dicen “ejemplo” con sus propias variables y métodos.

En primer lugar, importa lo que necesites en la actividad principal donde quieras que el botón de retorno haga algo especial:

 import android.view.inputmethod.EditorInfo; import android.widget.TextView; import android.view.KeyEvent; 

Ahora, crea una variable de tipo TextView.OnEditorActionListener para tu clave de retorno (aquí utilizo exampleListener );

 TextView.OnEditorActionListener exampleListener = new TextView.OnEditorActionListener(){ 

Luego debe decirle al oyente dos cosas sobre qué hacer cuando se presiona el botón de retorno. Necesita saber de qué EditText estamos hablando (aquí uso exampleView ), y luego necesita saber qué hacer cuando se presiona la tecla Enter (aquí, example_confirm () ). Si este es el último o único EditText en su actividad, debería hacer lo mismo que el método onClick para su botón Enviar (o Aceptar, Confirmar, Enviar, Guardar, etc.).

 public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) { example_confirm();//match this behavior to your 'Send' (or Confirm) button } return true; } 

Finalmente, configure el oyente (muy probablemente en su método onCreate);

 exampleView.setOnEditorActionListener(exampleListener); 
 final EditText edittext = (EditText) findViewById(R.id.edittext); edittext.setOnKeyListener(new OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // If the event is a key-down event on the "enter" button if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { // Perform action on key press Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show(); return true; } return false; } }); 

Los teclados de hardware siempre producen eventos de entrada, pero los teclados de software devuelven diferentes ID de acción y nulos en SingleLine EditTexts. Este código responde cada vez que el usuario presiona ingresar un EditText que este oyente ha establecido, independientemente de EditText o del tipo de teclado.

 import android.view.inputmethod.EditorInfo; import android.view.KeyEvent; import android.widget.TextView.OnEditorActionListener; listener=new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView view, 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. else if (actionId==EditorInfo.IME_ACTION_NEXT); // Capture soft enters in other singleLine EditTexts else return false; // Let system handle all other null KeyEvents } 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 key is first pressed. else return true; // We consume the event when the key is released. } else return false; // We let the system handle it when the listener // is triggered by something that wasn't an enter. // Code from this point on will execute whenever the user // presses enter in an attached view, regardless of position, // keyboard, or singleLine status. if (view==multiLineEditText) multiLineEditText.setText("You pressed enter"); if (view==singleLineEditText) singleLineEditText.setText("You pressed next"); if (view==lastSingleLineEditText) lastSingleLineEditText.setText("You pressed done"); return true; // Consume the event } }; 

La apariencia predeterminada de la tecla enter en singleLine = false da una flecha doblada para ingresar al teclado. Cuando singleLine = true en el último EditText, la clave dice DONE, y en los EditTexts anteriores dice NEXT. De forma predeterminada, este comportamiento es coherente en todos los emuladores de vanilla, android y google. El atributo scrollHorizontal no hace ninguna diferencia. La prueba nula es importante porque la respuesta de los teléfonos a entradas suaves se deja al fabricante e incluso en los emuladores, los emuladores vanilla de nivel 16 responden a entradas largas y suaves en multitrayectoria y scrollHorizontal EditTexts con una acción Id de NEXT y un nulo para el evento.

Sé que tiene un año, pero descubrí que esto funciona perfectamente para EditText.

 EditText textin = (EditText) findViewById(R.id.editText1); textin.setInputType(InputType.TYPE_CLASS_TEXT); 

Impide todo menos texto y espacio. No pude tab, “return” (“\ n”), ni nada.

Solo como una adición a la respuesta de Chad (que funcionó casi perfectamente para mí), descubrí que necesitaba agregar una marca en el tipo de acción KeyEvent para evitar que mi código se ejecutara dos veces (una vez en la tecla y otra en la tecla abajo evento).

 if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) { // your code here } 

Consulte http://developer.android.com/reference/android/view/KeyEvent.html para obtener información sobre la repetición de eventos de acción (manteniendo presionada la tecla Intro), etc.

Yo tenía un propósito similar. Quería resolver presionando la tecla “Enter” en el teclado (que quería personalizar) en un AutoCompleteTextView que amplía TextView. Intenté diferentes soluciones desde arriba y parecían funcionar. PERO tuve algunos problemas cuando cambié el tipo de entrada en mi dispositivo (Nexus 4 con AOKP ROM) de SwiftKey 3 (donde funcionaba perfectamente) al teclado estándar de Android (donde en lugar de manejar mi código del oyente, se creaba una nueva línea ingresado después de presionar la tecla “Enter”. Me tomó un tiempo manejar este problema, pero no sé si funcionará bajo cualquier circunstancia, sin importar qué tipo de entrada use.

Así que aquí está mi solución:

Establezca el atributo de tipo de entrada de TextView en el xml en “texto”:

 android:inputType="text" 

Personaliza la etiqueta de la tecla “Enter” en el teclado:

 myTextView.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER); 

Establezca OnEditorActionListener en TextView:

 myTextView.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { boolean handled = false; if (actionId == KeyEvent.KEYCODE_ENTER) { // Handle pressing "Enter" key here handled = true; } return handled; } }); 

Espero que esto pueda ayudar a otros a evitar los problemas que tuve, porque casi me volvieron loco.

Esta página describe exactamente cómo hacer esto.

https://developer.android.com/training/keyboard-input/style.html

Establezca el android: imeOptions luego solo verifique actionId en onEditorAction. Por lo tanto, si establece imeOptions en ‘actionDone’, debe verificar ‘actionId == EditorInfo.IME_ACTION_DONE’ en onEditorAction. Además, asegúrese de configurar el android: inputType.

Aquí está el EditText del ejemplo vinculado arriba:

  

También puede establecer esto mediante progtwigción utilizando la función setImeOptions (int) . Aquí está el OnEditorActionListener del ejemplo vinculado arriba:

 EditText editText = (EditText) findViewById(R.id.search); editText.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { boolean handled = false; if (actionId == EditorInfo.IME_ACTION_SEND) { sendMessage(); handled = true; } return handled; } }); 

En tu xml, agrega el atributo imeOptions a editText

  

Luego, en su código Java, agregue OnEditorActionListener al mismo EditText

 mAddItemEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if(actionId == EditorInfo.IME_ACTION_DONE){ //do stuff return true; } return false; } }); 

Aquí está la explicación: The imeOptions = actionDone asignará “actionDone” a EnterKey. EnterKey en el teclado cambiará de “Enter” a “Done”. Por lo tanto, cuando se presiona la tecla Enter, activará esta acción y, por lo tanto, la manejará.

También puedes hacerlo …

 editText.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { Log.i("event", "captured"); return false; } return false; } }); 
  password.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); submit.performClick(); return true; } return false; } }); 

Funciona muy bien para mí
Además ocultar el teclado

Primero, debes establecer EditText escuchar presionar la tecla

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set the EditText listens to key press EditText edittextproductnumber = (EditText) findViewById(R.id.editTextproductnumber); edittextproductnumber.setOnKeyListener(this); } 

En segundo lugar, defina el evento al presionar la tecla, por ejemplo, evento para establecer el texto de TextView:

 @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // TODO Auto-generated method stub // Listen to "Enter" key press if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { TextView textviewmessage = (TextView) findViewById(R.id.textViewmessage); textviewmessage.setText("You hit 'Enter' key"); return true; } return false; } 

Y finalmente, no te olvides de importar EditText, TextView, OnKeyListener, KeyEvent en la parte superior:

 import android.view.KeyEvent; import android.view.View.OnKeyListener; import android.widget.EditText; import android.widget.TextView; 

trabajando perfectamente

 public class MainActivity extends AppCompatActivity { TextView t; Button b; EditText e; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); b = (Button) findViewById(R.id.b); e = (EditText) findViewById(R.id.e); e.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (before == 0 && count == 1 && s.charAt(start) == '\n') { b.performClick(); e.getText().replace(start, start + 1, ""); //remove the  } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void afterTextChanged(Editable s) {} }); b.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { b.setText("ok"); } }); } 

}

trabajando perfectamente

Esto funciona bien en teléfonos con Android con LG. Impide que ENTER y otros caracteres especiales se interpreten como caracteres normales. Next botón Next o Done aparece automáticamente y ENTER funciona como se espera.

 edit.setInputType(InputType.TYPE_CLASS_TEXT); 

Esto debería funcionar

 input.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) {} @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if( -1 != input.getText().toString().indexOf( "\n" ) ){ input.setText("Enter was pressed!"); } } }); 

Una manera confiable de responder a un en un EditText es con un TextWatcher , un LocalBroadcastManager y un BroadcastReceiver . Necesita agregar la biblioteca de soporte v4 para usar LocalBroadcastManager. Utilizo el tutorial en vogella.com : 7.3 “Eventos de transmisión local con LocalBroadcastManager” debido a su completo código conciso. Ejemplo. En onTextChanged before es el índice del final del cambio antes del cambio >; menos inicio. Cuando en el TextWatcher el subproceso de la interfaz de usuario está ocupado actualizando EditText editable, enviamos un Intent para activar el BroadcastReceiver cuando el subproceso de la interfaz de usuario termina de actualizar EditText.

 import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.text.Editable; //in onCreate: editText.addTextChangedListener(new TextWatcher() { public void onTextChanged (CharSequence s, int start, int before, int count) { //check if exactly one char was added and it was an  if (before==0 && count==1 && s.charAt(start)=='\n') { Intent intent=new Intent("enter") Integer startInteger=new Integer(start); intent.putExtra("Start", startInteger.toString()); // Add data mySendBroadcast(intent); //in the BroadcastReceiver's onReceive: int start=Integer.parseInt(intent.getStringExtra("Start")); editText.getText().replace(start, start+1,""); //remove the  //respond to the  here 

InputType en el campo de texto debe ser “texto” para que funcione lo que dice CommonsWare. Acabo de probar todo esto, sin inputType antes de la prueba y nada funcionó, Enter siguió registrándose como soft enter. Después de inputType = text, todo lo que incluye setImeLabel funcionó.

 editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId != 0 || event.getAction() == KeyEvent.ACTION_DOWN) { // Action return true; } else { return false; } } }); 

Xml

  

La respuesta de Jared Law funciona como un encanto para mí.

acaba de agregar estos depencendy:

 import android.view.KeyEvent; import android.view.View; import android.widget.EditText; 

Aquí hay una función estática simple que puede incluir en su clase Utils o Keyboards que ejecutará el código cuando el usuario pulse la tecla de retorno en un teclado de hardware o software. Es una versión modificada de la excelente respuesta de @ earlcasper

  /** * Return a TextView.OnEditorActionListener that will execute code when an enter is pressed on * the keyboard.
*
* myTextView.setOnEditorActionListener(Keyboards.onEnterEditorActionListener(new Runnable()->{ * Toast.makeText(context,"Enter Pressed",Toast.LENGTH_SHORT).show(); * })); * * @param doOnEnter A Runnable for what to do when the user hits enter * @return the TextView.OnEditorActionListener */ public static TextView.OnEditorActionListener onEnterEditorActionListener(final Runnable doOnEnter){ return (__, actionId, event) -> { if (event==null) { if (actionId == EditorInfo.IME_ACTION_DONE) { // Capture soft enters in a singleLine EditText that is the last EditText. doOnEnter.run(); return true; } else if (actionId==EditorInfo.IME_ACTION_NEXT) { // Capture soft enters in other singleLine EditTexts doOnEnter.run(); return true; } else { return false; // Let system handle all other null KeyEvents } } 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 key is first pressed. return true; } else { doOnEnter.run(); return true; // We consume the event when the key is released. } } else { // We let the system handle it when the listener // is triggered by something that wasn't an enter. return false; } }; }