Android: maneja "Enter" en un EditText

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

También se pregunta si hay una manera de manipular el teclado virtual de tal manera que el botón "Hecho" se etiqueta algo más (por ejemplo "Go") y realiza una cierta acción cuando se hace clic (de nuevo, como onSubmit).

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

Sí.

También se pregunta si hay una manera de manipular el teclado virtual de tal manera que el botón "Hecho" se etiqueta algo más (por ejemplo "Go") y realiza una cierta acción cuando se hace clic (de nuevo, como onSubmit).

También sí.

Usted querrá ver los android:imeActionId y android:imeOptions , más el método setOnEditorActionListener() , todo en TextView .

Para cambiar el texto del botón "Hecho" a una cadena personalizada, utilice:

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

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

Primero, importa lo que necesitas en la actividad principal donde quieres que el botón de retorno haga algo especial:

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

Ahora, haga una variable del tipo TextView.OnEditorActionListener para su llave de vuelta (aquí uso exampleListener );

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

Entonces usted necesita decir al oyente dos cosas acerca de qué hacer cuando se presiona el botón de retorno. Necesita saber de qué EditText estamos hablando (aquí utilizo exampleView ), y entonces necesita saber qué hacer cuando se pulsa la tecla Enter (aquí, example_confirm () ). Si este es el último o único EditText de su Actividad, debe 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; } 

Por último, establecer 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 entrar en un EditText que este oyente se ha establecido, independientemente de EditText o 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 } }; 

El aspecto predeterminado de la tecla enter en singleLine = false da una flecha doblada al teclado. Cuando singleLine = true en el último EditText la llave dice HECHO, y en el EditTexts antes de él dice NEXT. De forma predeterminada, este comportamiento es consistente en todos los emuladores de vainilla, android y google. El atributo scrollHorizontal no hace ninguna diferencia. La prueba nula es importante porque la respuesta de los teléfonos a las entradas de software se deja para el fabricante e incluso en los emuladores, los emuladores de nivel 16 de vainilla responden a las entradas de software largas en multi-line y scrollHorizontal EditTexts con un actionId de NEXT y un null para el evento.

Sé que esto es un año de edad, pero acabo de descubrir que esto funciona perfectamente para un EditText.

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

Evita cualquier cosa pero texto y espacio. No pude tabular, "return" ("\ n"), ni nada.

Al igual que un complemento a la respuesta de Chad (que funcionó casi perfectamente para mí), me encontré con que tenía que añadir una comprobación en el tipo de acción KeyEvent para evitar que mi código de ejecución dos veces (una vez en el key-up y una vez en el key-down 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 pulsada 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 extiende TextView. Traté de diferentes soluciones de arriba y parecían funcionar. Pero he experimentado algunos problemas cuando cambié el tipo de entrada en mi dispositivo (Nexus 4 con AOKP ROM) de SwiftKey 3 (donde funcionó perfectamente) al teclado estándar de Android (donde en lugar de manejar mi código del oyente, una nueva línea fue Entró después de presionar la tecla "Enter". Me tomó un tiempo para manejar este problema, pero no sé si funcionará en todas las circunstancias no importa qué tipo de entrada que utiliza.

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

Establezca el atributo de tipo de entrada de TextView en el xml a "text":

 android:inputType="text" 

Personalizar 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 volví loco.

En su xml, agregue el atributo imeOptions al editText

 <EditText android:id="@+id/edittext_additem" ... android:imeOptions="actionDone" /> 

A continuación, 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 la EnterKey. El EnterKey en el teclado cambiará de "Enter" a "Done". Por lo tanto, cuando se pulsa la tecla Enter, activará esta acción y así lo 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; } }); 

Esta página describe exactamente cómo hacerlo.

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

Establecer el android: imeOptions entonces acaba de comprobar el actionId en onEditorAction. Así que si establece imeOptions en 'actionDone', entonces buscará 'actionId == EditorInfo.IME_ACTION_DONE' en onEditorAction. Además, asegúrese de establecer el android: inputType.

Aquí está el EditText del ejemplo enlazado arriba:

 <EditText android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/search_hint" android:inputType="text" android:imeOptions="actionSend" /> 

También puede establecer esta programación mediante 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; } }); 
  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, oculte el teclado

En primer lugar, tienes que 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 las teclas, 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 olvide 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 <enter> } } @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 los teléfonos Android de LG. Evita 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 esperaba.

 edit.setInputType(InputType.TYPE_CLASS_TEXT); 

Una forma fiable de responder a un <enter> en un EditText es con un TextWatcher , un LocalBroadcastManager y un BroadcastReceiver . Debe agregar la biblioteca de soporte v4 para utilizar LocalBroadcastManager. Yo uso el tutorial en vogella.com : 7.3 "Eventos de difusión local con LocalBroadcastManager" debido a su código conciso completo Ejemplo. En onTextChanged antes es el índice del final del cambio antes del cambio >; menos el inicio. Cuando en el TextWatcher el subproceso de la interfaz de usuario está ocupado actualizando EditText editable, por lo que enviamos una intención de despertar el BroadcastReceiver cuando el hilo de la interfaz de usuario se realiza la actualización 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 <enter> 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 <enter> //respond to the <enter> here 

InputType en el campo de texto debe ser "texto" para que lo que CommonsWare dijo que funcione. Acabo de probar todo esto, no inputType antes de la prueba y nada funcionó, Enter mantuvo registro como soft enter. Después de inputType = texto, todo lo que incluye el 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

 <EditText android:id="@+id/editText2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/password" android:imeOptions="actionGo|flagNoFullscreen" android:inputType="textPassword" android:maxLines="1" /> 

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

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

Sólo agregó estos depencendy:

 import android.view.KeyEvent; import android.view.View; import android.widget.EditText; 
  • Autosizing de TextView no funciona (Android O)
  • ¿Por qué se envuelve el contenido en la línea múltiple TextView fill parent?
  • Mantener texto en TextView con drawableLeft centrado
  • Cómo hacer que el TextView arrastre en LinearLayout suave, en android?
  • Sombra interna en Android TextView
  • ¿Cómo hacer cursivo el trabajo de TextView en la vista de diseño gráfico de Eclipse? Incluso cuelga el PC
  • Disposición de Android - peso de diseño y weightsum
  • Android redondeado esquina textview con redondeo perfecto en la esquina
  • Establecer color de fondo en sólo (1/4) th parte de una vista (Android)
  • Evitar el empaquetado de palabras en ciertas palabras (nombre de dominio) en android
  • Android TextView no se puede seleccionar en CoordinatorLayout? (TextView no admite la selección de texto.
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.