EditText maxLines not working - user can still input more lines than set

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

User can input more than 5 lines, by pressing enter/next row key. How can I limit user input to fixed amount of rows with EditText?

103944 次浏览

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

@ Cedekasem 你说得对,没有内置的行限制器。但我自己做了一个,所以如果有人感兴趣的代码如下。干杯。

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

这并不能解决限制在 n 行的一般问题。如果您希望将 EditText 限制为只包含1行文本,那么这非常简单。
您可以在 xml 文件中设置它。

android:singleLine="true"

或者程序化

editText.setSingleLine(true);

GetLineCount ()是一个选项; 如果您想要非零值,那么请确保您的视图是度量的。对于软键盘 onKeyListener 不工作,所以您必须添加 AddTextChangedListener () ,它将在您键入时跟踪文本更改。一旦在它的回调中获得了足够多的行,就可以做任何您想要限制它的事情: 使用 getText ()、 setText ()或其他更花哨的方法删除字符。您甚至可以使用筛选器限制字符数。

另一个选项是使用 getLineBound ()来监视文本的大小。

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

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

而且在所有情况下都有效

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

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

特点:

  • 可以限制 LimitedEditText 组件中的行数
  • 可以限制 LimitedEditText 组件中的字符数
  • 如果你在文本中间的某个地方超过了字符或行的限制,光标 < br > 不会把你带到最后-它会停留在你去过的地方。

我关闭了侦听器,因为当用户超过字符或行数限制时,setText()方法的每次调用都会递归地调用这3个回调方法。

密码:

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


}

下面是一个 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)});

我已经为这个问题提出了更简单的解决方案: 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。

最简单的解决办法:

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

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

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

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

editText2.setTransformationMethod(new SingleLineTransformationMethod());

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

这是个办法,也许能帮上忙。

android:lines="1"
android:maxLines="1"
android:inputType="text
        <EditText
android:id="@+id/usrusr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:lines="1"
android:maxLines="1"
android:inputType="text"
android:hint="@string/inventory_no" />

你可以限制你的文字根据你的行号我说大约37个字母在一行

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="4"
android:maxLines="4"
android:minLines="4"
android:maxLength="150"
android:gravity="start"
android:background="#efeef5"
android:layout_marginTop="@dimen/pad_10dp"/>

设置编辑文本 android:inputType="text"

android:inputType="text" (or something different to "none")
android:maxLines="1"  (and this line)

另一个想法是: 每次键入之后,只有当行数不超过 MAX _ LINES 时,新的文本才会保存到一个 String lastText 中。如果是这样,我们将把 EditText 的文本设置为最后添加的文本(这样更改将被删除) ,并通知用户保持简短。

 // Set listener to wishDescriptionEditText in order to limit line number
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}


@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}


@Override
public void afterTextChanged(Editable s) {
// If line account is higher than MAX_LINES, set text to lastText
// and notify user (by Toast)
if (editText.getLineCount() > MAX_LINES) {
editText.setText(lastText);
Toast.makeText(getContext(), "Please keep it short", Toast.LENGTH_LONG).show();
} else {
lastText = editText.getText().toString();
}
}
});

这是 ABc0对 Kotlin 的扩展

                input_name.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {}


override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}


@SuppressLint("SetTextI18n")
override fun onTextChanged(
s: CharSequence?,
start: Int,
before: Int,
count: Int
) {
val text = (input_name as EditText).text.toString()
val editTextRowCount = input_name.lineCount
if (editTextRowCount > 15) {
val newText = text.substring(0, text.length - 1)
input_name.setText("")
input_name.append(newText)
}
}
})