EditText maxLines no funciona: el usuario puede seguir ingresando más líneas que las configuradas

  

El usuario puede ingresar más de 5 líneas, al presionar la tecla enter / next row. ¿Cómo puedo limitar la entrada del usuario a una cantidad fija de filas con EditText?

El atributo maxLines corresponde a la altura máxima de EditText , controla los límites externos y no las líneas de texto internas.

  

Solo necesita asegurarse de tener el atributo “inputType” establecido. No funciona sin esta línea.

 android:inputType="text" 

Esto no resuelve el problema general de limitar a n líneas. Si desea limitar su EditText para tomar solo 1 línea de texto, esto puede ser muy fácil.
Puede configurar esto en el archivo xml.

 android:singleLine="true" 

o programáticamente

 editText.setSingleLine(true); 

@Cedekasem tiene razón, no hay un “limitador de filas” incorporado. Pero sí construí uno, así que si alguien está interesado, el código está debajo. Aclamaciones.

 et.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // if enter is pressed start calculating if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { // get EditText text String text = ((EditText) v).getText().toString(); // find how many rows it cointains int editTextRowCount = text.split("\\n").length; // user has input more than limited - lets do something // about that if (editTextRowCount >= 7) { // find the last break int lastBreakIndex = text.lastIndexOf("\n"); // compose new text String newText = text.substring(0, lastBreakIndex); // add new text - delete old one and append new one // (append because I want the cursor to be at the end) ((EditText) v).setText(""); ((EditText) v).append(newText); } } return false; } }); 

Hice algo como ustedes que han estado buscando. Aquí está mi clase LimitedEditText .

caracteristicas:

  • puede limitar el número de líneas en su componente LimitedEditText
  • puede limitar el número de caracteres en su componente LimitedEditText
  • si excede el límite de caracteres o líneas en algún lugar en el medio del texto, cursor
    no te llevará al final, permanecerá donde has estado.

Estoy apagando el oyente, porque cada llamada del método setText() llamaría recursivamente estos 3 métodos de callback en caso de que el usuario excediera los caracteres o el límite de las líneas.

Código:

 import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; import android.widget.EditText; import android.widget.Toast; /** * EditText subclass created to enforce limit of the lines number in editable * text field */ public class LimitedEditText extends EditText { /** * Max lines to be present in editable text field */ private int maxLines = 1; /** * Max characters to be present in editable text field */ private int maxCharacters = 50; /** * application context; */ private Context context; public int getMaxCharacters() { return maxCharacters; } public void setMaxCharacters(int maxCharacters) { this.maxCharacters = maxCharacters; } @Override public int getMaxLines() { return maxLines; } @Override public void setMaxLines(int maxLines) { this.maxLines = maxLines; } public LimitedEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.context = context; } public LimitedEditText(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; } public LimitedEditText(Context context) { super(context); this.context = context; } @Override protected void onFinishInflate() { super.onFinishInflate(); TextWatcher watcher = new TextWatcher() { private String text; private int beforeCursorPosition = 0; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //TODO sth } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { text = s.toString(); beforeCursorPosition = start; } @Override public void afterTextChanged(Editable s) { /* turning off listener */ removeTextChangedListener(this); /* handling lines limit exceed */ if (LimitedEditText.this.getLineCount() > maxLines) { LimitedEditText.this.setText(text); LimitedEditText.this.setSelection(beforeCursorPosition); } /* handling character limit exceed */ if (s.toString().length() > maxCharacters) { LimitedEditText.this.setText(text); LimitedEditText.this.setSelection(beforeCursorPosition); Toast.makeText(context, "text too long", Toast.LENGTH_SHORT) .show(); } /* turning on listener */ addTextChangedListener(this); } }; this.addTextChangedListener(watcher); } } 

He hecho una solución más simple para esto: D

 // set listeners txtSpecialRequests.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { lastSpecialRequestsCursorPosition = txtSpecialRequests.getSelectionStart(); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { txtSpecialRequests.removeTextChangedListener(this); if (txtSpecialRequests.getLineCount() > 3) { txtSpecialRequests.setText(specialRequests); txtSpecialRequests.setSelection(lastSpecialRequestsCursorPosition); } else specialRequests = txtSpecialRequests.getText().toString(); txtSpecialRequests.addTextChangedListener(this); } }); 

Puede cambiar el valor de 3 en txtSpecialRequests.getLineCount() > 3 según sus necesidades.

Aquí hay un InputFilter que limita las líneas permitidas en EditText:

 /** * Filter for controlling maximum new lines in EditText. */ public class MaxLinesInputFilter implements InputFilter { private final int mMax; public MaxLinesInputFilter(int max) { mMax = max; } public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { int newLinesToBeAdded = countOccurrences(source.toString(), '\n'); int newLinesBefore = countOccurrences(dest.toString(), '\n'); if (newLinesBefore >= mMax - 1 && newLinesToBeAdded > 0) { // filter return ""; } // do nothing return null; } /** * @return the maximum lines enforced by this input filter */ public int getMax() { return mMax; } /** * Counts the number occurrences of the given char. * * @param string the string * @param charAppearance the char * @return number of occurrences of the char */ public static int countOccurrences(String string, char charAppearance) { int count = 0; for (int i = 0; i < string.length(); i++) { if (string.charAt(i) == charAppearance) { count++; } } return count; } } 

Para agregarlo a EditText:

 editText.setFilters(new InputFilter[]{new MaxLinesInputFilter(2)}); 

Esto es lo que utilicé en mi proyecto:

 editText.addTextChangedListener(new TextWatcher() { private String text; public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { text = arg0.toString(); } public void afterTextChanged(Editable arg0) { int lineCount = editText.getLineCount(); if(lineCount > numberOfLines){ editText.setText(text); } } }); editText.setOnKeyListener(new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // if enter is pressed start calculating if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN){ int editTextLineCount = ((EditText)v).getLineCount(); if (editTextLineCount >= numberOfLines) return true; } return false; } }); 

Y funcionó en todos los escenarios

Otra forma de limitar tu EditText a una línea es la siguiente:

 editText2.setTransformationMethod(new SingleLineTransformationMethod()); 

Tenga en cuenta que después de aplicar este método de transformación, la tecla Intro crea espacios cuando se presiona. Eso todavía satisface la pregunta de TS.

getLineCount () es una opción; si desea valores distintos de cero, asegúrese de medir su vista. Para el teclado suave onKeyListener no funcionará, por lo que debe agregar addTextChangedListener () que rastreará los cambios de texto a medida que escribe. Tan pronto como tengas suficientes líneas dentro de sus call backs haz lo que quieras para limitarlo: elimina los caracteres con getText (), setText () o algo más sofisticado. Incluso puede limitar el número de caracteres usando un filtro.

Otra opción es controlar el tamaño del texto con getLineBounds (). Esto interactuará con la gravedad del texto / paddign así que ten cuidado.

Para limitar el número de caracteres, simplemente podemos usar la propiedad maxLength de EditText, ya que no permitirá al usuario ingresar más caracteres.

La solución más simple:

 android:maxLines="3" 

  @Override public void afterTextChanged(Editable editable) { // limit to 3 lines if (editText.getLayout().getLineCount() > 3) editText.getText().delete(editText.getText().length() - 1, editText.getText().length()); } 

este es un enfoque. Podría ayudar a alguien.

 android:lines="1" android:maxLines="1" android:inputType="text 

Intente utilizar la siguiente combinación de atributos de EditText dentro del archivo xml:

android:singleLine="true"
android:maxLength="22"