在Android中限制EditText文本长度的最佳方法是什么?
有没有通过xml实现这一点的方法?
在Android中限制EditText文本长度的最佳方法是什么?
有没有通过xml实现这一点的方法?
当前回答
由于goto10的观察,我将以下代码组合在一起,通过设置最大长度来防止丢失其他过滤器:
/**
* This sets the maximum length in characters of an EditText view. Since the
* max length must be done with a filter, this method gets the current
* filters. If there is already a length filter in the view, it will replace
* it, otherwise, it will add the max length filter preserving the other
*
* @param view
* @param length
*/
public static void setMaxLength(EditText view, int length) {
InputFilter curFilters[];
InputFilter.LengthFilter lengthFilter;
int idx;
lengthFilter = new InputFilter.LengthFilter(length);
curFilters = view.getFilters();
if (curFilters != null) {
for (idx = 0; idx < curFilters.length; idx++) {
if (curFilters[idx] instanceof InputFilter.LengthFilter) {
curFilters[idx] = lengthFilter;
return;
}
}
// since the length filter was not part of the list, but
// there are filters, then add the length filter
InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
newFilters[curFilters.length] = lengthFilter;
view.setFilters(newFilters);
} else {
view.setFilters(new InputFilter[] { lengthFilter });
}
}
其他回答
xml中的简单方式:
android:maxLength="@{length}"
要以编程方式设置它,可以使用以下函数
public static void setMaxLengthOfEditText(EditText editText, int length) {
InputFilter[] filters = editText.getFilters();
List arrayList = new ArrayList();
int i2 = 0;
if (filters != null && filters.length > 0) {
int filtersSize = filters.length;
int i3 = 0;
while (i2 < filtersSize) {
Object obj = filters[i2];
if (obj instanceof LengthFilter) {
arrayList.add(new LengthFilter(length));
i3 = 1;
} else {
arrayList.add(obj);
}
i2++;
}
i2 = i3;
}
if (i2 == 0) {
arrayList.add(new LengthFilter(length));
}
if (!arrayList.isEmpty()) {
editText.setFilters((InputFilter[]) arrayList.toArray(new InputFilter[arrayList.size()]));
}
}
xml中的简单方式:
android:maxLength="4"
如果您需要在xml编辑文本中设置4个字符,请使用
<EditText
android:id="@+id/edtUserCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="4"
android:hint="Enter user code" />
这是一个自定义的EditText类,允许长度筛选器与其他筛选器一起使用。感谢Tim Gallagher的回答(如下)
import android.content.Context;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.widget.EditText;
public class EditTextMultiFiltering extends EditText{
public EditTextMultiFiltering(Context context) {
super(context);
}
public EditTextMultiFiltering(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextMultiFiltering(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setMaxLength(int length) {
InputFilter curFilters[];
InputFilter.LengthFilter lengthFilter;
int idx;
lengthFilter = new InputFilter.LengthFilter(length);
curFilters = this.getFilters();
if (curFilters != null) {
for (idx = 0; idx < curFilters.length; idx++) {
if (curFilters[idx] instanceof InputFilter.LengthFilter) {
curFilters[idx] = lengthFilter;
return;
}
}
// since the length filter was not part of the list, but
// there are filters, then add the length filter
InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
newFilters[curFilters.length] = lengthFilter;
this.setFilters(newFilters);
} else {
this.setFilters(new InputFilter[] { lengthFilter });
}
}
}
科特林:
edit_text.filters += InputFilter.LengthFilter(10)
中兴刀片A520具有奇怪的效果。当您键入超过10个符号(例如15个)时,EditText将显示前10个符号,但其他5个符号不可见且不可访问。但当您使用Backspace删除符号时,它会先删除右边的5个符号,然后删除剩下的10个符号。要克服这种行为,请使用以下解决方案:
android:inputType="textNoSuggestions|textVisiblePassword"
android:maxLength="10"
或者:
android:inputType="textNoSuggestions"
或者,如果您想获得建议:
private class EditTextWatcher(private val view: EditText) : TextWatcher {
private var position = 0
private var oldText = ""
override fun afterTextChanged(s: Editable?) = Unit
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
oldText = s?.toString() ?: ""
position = view.selectionStart
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val newText = s?.toString() ?: ""
if (newText.length > 10) {
with(view) {
setText(oldText)
position = if (start > 0 && count > 2) {
// Text paste in nonempty field.
start
} else {
if (position in 1..10 + 1) {
// Symbol paste in the beginning or middle of the field.
position - 1
} else {
if (start > 0) {
// Adding symbol to the end of the field.
start - 1
} else {
// Text paste in the empty field.
0
}
}
}
setSelection(position)
}
}
}
}
// Usage:
editTextWatcher = EditTextWatcher(view.edit_text)
view.edit_text.addTextChangedListener(editTextWatcher)
我看到了很多好的解决方案,但我想给出一个我认为更完整、更人性化的解决方案:
1、限制长度。2、如果输入更多,则发出回调以触发吐司。3、光标可以在中间或尾部。4、用户可以通过粘贴字符串进行输入。5、始终丢弃溢出输入并保留原点。
public class LimitTextWatcher implements TextWatcher {
public interface IF_callback{
void callback(int left);
}
public IF_callback if_callback;
EditText editText;
int maxLength;
int cursorPositionLast;
String textLast;
boolean bypass;
public LimitTextWatcher(EditText editText, int maxLength, IF_callback if_callback) {
this.editText = editText;
this.maxLength = maxLength;
this.if_callback = if_callback;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (bypass) {
bypass = false;
} else {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(s);
textLast = stringBuilder.toString();
this.cursorPositionLast = editText.getSelectionStart();
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.toString().length() > maxLength) {
int left = maxLength - s.toString().length();
bypass = true;
s.clear();
bypass = true;
s.append(textLast);
editText.setSelection(this.cursorPositionLast);
if (if_callback != null) {
if_callback.callback(left);
}
}
}
}
edit_text.addTextChangedListener(new LimitTextWatcher(edit_text, MAX_LENGTH, new LimitTextWatcher.IF_callback() {
@Override
public void callback(int left) {
if(left <= 0) {
Toast.makeText(MainActivity.this, "input is full", Toast.LENGTH_SHORT).show();
}
}
}));
我没能做到的是,如果用户高亮显示当前输入的一部分并试图粘贴一个很长的字符串,我不知道如何恢复高亮显示。
例如,最大长度设置为10,用户输入“12345678”,并将“345”标记为突出显示,然后尝试粘贴一个超过限制的字符串“0000”。
当我尝试使用edit_text.setSelection(start=2,end=4)恢复原点状态时,结果是,它只插入2个空格作为“12 345 678”,而不是原点高亮显示。我希望有人解决这个问题。