¿Cómo hago un EditText en Android de modo que el usuario no pueda ingresar un texto de varias líneas, pero la pantalla sigue siendo de varias líneas (es decir, hay ajuste de línea en lugar de que el texto vaya hacia la derecha)?
Es similar a la aplicación de SMS integrada en la que no podemos ingresar líneas nuevas, pero el texto se muestra en varias líneas.
tony el pony
Subclasificaría el widget y anularía el manejo de eventos clave para bloquear el Enter
llave:
class MyTextView extends EditText
{
...
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode==KeyEvent.KEYCODE_ENTER)
{
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return super.onKeyDown(keyCode, event);
}
}
-
Si esta línea:
return super.onKeyDown(keyCode, event);
estar en onKeyDown o estoy imaginando? :PAGS– necixy
20 de mayo de 2011 a las 11:04
-
Ambos estamos trabajando para la misma comunidad. De nada Jen. 🙂
– necixy
20 de mayo de 2011 a las 11:16
-
Gracias por tu respuesta. (Subí la otra respuesta también). Sugerencia: puede evitar la creación de subclases simplemente editText.setOnKeyListener(…) y regresar (keyCode == KeyEvent.KEYCODE_ENTER).
– Randy Sugianto ‘Yuku’
23 de mayo de 2011 a las 3:09
-
la tecla enter sigue funcionando en nexus con diseño lineal
– Dr. ANDRO
11 de febrero de 2014 a las 4:26
-
Casi ningún teclado envía eventos clave. Esos están destinados a las llaves de hardware. Casi todos usan commitText, que no llamará a esta función.
– Gabe Sechan
15 de junio de 2017 a las 20:59
andreas rodolfo
Este es un método en el que no tiene que anular la clase EditText. Simplemente captura y reemplaza las líneas nuevas con cadenas vacías.
edittext.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
/*
* The loop is in reverse for a purpose,
* each replace or delete call on the Editable will cause
* the afterTextChanged method to be called again.
* Hence the return statement after the first removal.
* http://developer.android.com/reference/android/text/TextWatcher.html#afterTextChanged(android.text.Editable)
*/
for(int i = s.length()-1; i >= 0; i--){
if(s.charAt(i) == '\n'){
s.delete(i, i + 1);
return;
}
}
}
});
Crédito a Rolf por mejorar en una respuesta anterior.
-
+1 Esto fue más útil en mi caso que la respuesta aceptada, por la sencilla razón de que puedo usarlo como una implementación predeterminada de TextWatcher, que puede expandirse por subclases (que luego simplemente llamaría a super.afterTextChanged(… ) para retener ese control de saltos de línea.
– AgenteKnopf
11 de julio de 2012 a las 10:42
-
La condición de bucle for debe ser
i > 0
más bien quei >= 0
. Cuandoi == 0
,s.subSequence(i-1, i)
obtiene unIndexOutOfBoundsException
.– TalkLittle
4 de noviembre de 2014 a las 22:01
-
Creo que esto arroja una excepción IndexOutOfBoundsException para el texto con una nueva línea que se copia y pega con varios caracteres de nueva línea.
– Chriskot
24 de marzo de 2015 a las 0:17
-
@TalkLittle Publiqué otra respuesta con el código correcto, solo cambiar la condición del bucle for no soluciona la excepción IndexOufOfBoundsException. Vea mi respuesta: stackoverflow.com/a/36485266/1052697
– Rolf ツ
07/04/2016 a las 19:20
Propiedad en XML
android:lines="5"
android:inputType="textPersonName"
-
Gracias, el más simple! Aunque noté que impedía que mi detector de clics en el ET funcionara … así que use
editText.setSingleLine(false);
en cambio si es así.– Azurespot
13 mayo 2016 a las 7:00
-
Esto depende totalmente del teclado utilizado. Muchos seguirán mostrando una tecla enter
– Gabe Sechan
15/06/2017 a las 21:00
Esta funciona para mí:
<EditText
android:inputType="textShortMessage|textMultiLine"
android:minLines="3"
... />
Muestra un emoticón en lugar de la tecla Intro.
Aquí hay una respuesta más correcta que no muestra la tecla Intro en el teclado IME:
// IMPORTANT, do this before any of the code following it
myEditText.setSingleLine(true);
// IMPORTANT, to allow wrapping
myEditText.setHorizontallyScrolling(false);
// IMPORTANT, or else your edit text would wrap but not expand to multiple lines
myEditText.setMaxLines(6);
Además, puede reemplazar setSingleLine(true)
con cualquiera, un explícito android:inputType
en el archivo de diseño XML, o setInputType(InputType.*)
en el código: en el que, el tipo de entrada utilizado, es cualquier cosa que sepa que restringe la entrada solo a líneas individuales (es decir, cualquier cosa que llame setSingleLine(true)
implícitamente ya).
Explicación:
Qué setSingleLine(true)
lo que hace es llamar setHorizontallyScrolling(true)
y setLines(1)
implícitamente, junto con la alteración de algunas configuraciones del teclado IME para deshabilitar la tecla Intro.
A su vez, la llamada a setLines(1)
es como llamar setMinLines(1)
y setMaxLines(1)
en una llamada
Algunos tipos de entrada (es decir, las constantes de InputType.TYPE_*
) llamadas setSingleLine(true)
implícitamente, o al menos logra el mismo efecto.
Conclusión:
Entonces, para lograr lo que quiere el OP, simplemente contrarrestamos esas configuraciones implícitas revirtiendo esas llamadas implícitas.
La respuesta proporcionada por @Andreas Rudolph contiene un error crítico y no debe usarse. El código provoca una IndexOutOfBoundsException
cuando pasas texto dentro del EditText
que contiene varios caracteres de nueva línea. Esto es causado por el tipo de bucle que se utiliza, la Editable
el objeto llamará al afterTextChanged
método tan pronto como cambie su contenido (reemplazar, eliminar, insertar).
Código correcto:
edittext.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
/*
* The loop is in reverse for a purpose,
* each replace or delete call on the Editable will cause
* the afterTextChanged method to be called again.
* Hence the return statement after the first removal.
* http://developer.android.com/reference/android/text/TextWatcher.html#afterTextChanged(android.text.Editable)
*/
for(int i = s.length()-1; i >= 0; i--){
if(s.charAt(i) == '\n'){
s.delete(i, i + 1);
return;
}
}
}
});
broschb
Estoy probando esto y parece funcionar:
EditText editText = new EditText(context);
editText.setSingleLine(false);
editText.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT);
-
Genial gracias. Establecer cualquier cosa en el XML estaba deshabilitando mis oyentes de clics ET… ¡así que hacerlo de esta manera no lo hizo! La tecla de retorno del teclado cambia a un botón “Listo”. (Solo necesitaba el
editText.setSingleLine(false);
).– Azurespot
13 de mayo de 2016 a las 6:59
-
Esto depende totalmente del teclado utilizado. Muchos seguirán mostrando una tecla enter
– Gabe Sechan
15 de junio de 2017 a las 21:01
simplemente agregue android: inputType = “textPersonName” al EditText, evitará que presione enter
– Zar E. Ahmer
21 de mayo de 2014 a las 11:06