EditText maxLines不工作 – 用户仍然可以input比设置更多的行

<EditText android:id="@+id/editText2" android:layout_height="wrap_content" android:layout_width="fill_parent" android:maxLines="5" android:lines="5"> </EditText> 

用户可以input5行以上,按enter / next row键。 如何使用EditText将用户input限制为固定数量的行?

maxLines属性对应于EditText的最大高度,它控制着外部边界而不是内部文本行。

 <EditText android:id="@+id/edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" android:maxLines="1" /> 

你只需要确保你有属性“inputType”设置。 没有这条线是行不通的。

 android:inputType="text" 

这并不能解决限制n行的一般问题。 如果你想限制你的EditText只占用一行文本,这可能非常容易。
你可以在xml文件中设置它。

 android:singleLine="true" 

或以编程方式

 editText.setSingleLine(true); 

@Cedekasem你是对的,没有一个内置的“行限制”。 但我确实build立了一个我自己,所以如果任何人有兴趣的代码是在下面。 干杯。

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

我做了一些像你们一直在寻找的东西。 这是我的LimitedEditText类。

特征:

  • 您可以限制您的LimitedEditText组件的行数
  • 您可以限制您的LimitedEditText组件中的字符数
  • 如果超出文本中间某处的字符或行的限制,则为光标
    不会把你带到最后 – 它会留在你去过的地方。

Imclosures监听器,因为每当调用setText()方法都会recursion地调用这3个callback方法,以防用户超出字符数或行数限制。

码:

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

我为此做了更简单的解决scheme: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); } }); 

您可以将txtSpecialRequests.getLineCount() > 3的值3更改为您的需要。

这里是一个InputFilter,它限制了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; } } 

要将其添加到EditText:

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

这是我在我的项目中使用的:

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

它适用于所有情况

getLineCount()是一个选项; 如果你想要非零值,那么确保你的视图是测量的。 对于软键盘,onKeyListener将不起作用,因此您必须添加addTextChangedListener(),以便在input时跟踪文本更改。 只要你在callback中得到足够的行,就可以做任何你想限制的行:用getText(),setText()或更特别的东西来删除字符。 你甚至可以使用filter限制字符的数量。

另一种select是用getLineBounds()监视文本的大小。 这将与文本重力/ paddign交互,所以要小心。

对于字符数限制,我们可以简单地使用EditText的maxLength属性,因为它不允许用户input更多的字符。

最简单的解决scheme

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

尝试在xml文件中使用EditText的以下属性组合:

android:singleLine="true"
android:maxLenght="22"

另一种将EditText限制为一行的方法如下:

 editText2.setTransformationMethod(new SingleLineTransformationMethod()); 

请注意,应用此转换方法后,按下Enter键时会创build空格。 这仍然满足TS的问题。