Limit text length of EditText in Android
什么是限制Android中
有没有办法通过xml做到这一点?
文档
例
1 | android:maxLength="10" |
使用输入过滤器来限制文本视图的最大长度。
1 2 3 4 | TextView editEntryView = new TextView(...); InputFilter[] filterArray = new InputFilter[1]; filterArray[0] = new InputFilter.LengthFilter(8); editEntryView.setFilters(filterArray); |
1 2 3 | EditText editText = new EditText(this); int maxLength = 3; editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)}); |
对已经使用自定义输入过滤器并且还想限制最大长度的人的注释:
在代码中分配输入过滤器时,将清除所有先前设置的输入过滤器,包括一组
1 2 3 | myEditText.setFilters(new InputFilter[] { new PasswordCharFilter(), new InputFilter.LengthFilter(20) }); |
1 2 | TextView tv = new TextView(this); tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) }); |
对于其他想知道如何实现这一点的人来说,这是我的扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | import android.content.Context; import android.text.InputFilter; import android.text.InputType; import android.widget.EditText; public class EditTextNumeric extends EditText { protected int max_value = Integer.MAX_VALUE; protected int min_value = Integer.MIN_VALUE; // constructor public EditTextNumeric(Context context) { super(context); this.setInputType(InputType.TYPE_CLASS_NUMBER); } // checks whether the limits are set and corrects them if not within limits @Override protected void onTextChanged(CharSequence text, int start, int before, int after) { if (max_value != Integer.MAX_VALUE) { try { if (Integer.parseInt(this.getText().toString()) > max_value) { // change value and keep cursor position int selection = this.getSelectionStart(); this.setText(String.valueOf(max_value)); if (selection >= this.getText().toString().length()) { selection = this.getText().toString().length(); } this.setSelection(selection); } } catch (NumberFormatException exception) { super.onTextChanged(text, start, before, after); } } if (min_value != Integer.MIN_VALUE) { try { if (Integer.parseInt(this.getText().toString()) < min_value) { // change value and keep cursor position int selection = this.getSelectionStart(); this.setText(String.valueOf(min_value)); if (selection >= this.getText().toString().length()) { selection = this.getText().toString().length(); } this.setSelection(selection); } } catch (NumberFormatException exception) { super.onTextChanged(text, start, before, after); } } super.onTextChanged(text, start, before, after); } // set the max number of digits the user can enter public void setMaxLength(int length) { InputFilter[] FilterArray = new InputFilter[1]; FilterArray[0] = new InputFilter.LengthFilter(length); this.setFilters(FilterArray); } // set the maximum integer value the user can enter. // if exeeded, input value will become equal to the set limit public void setMaxValue(int value) { max_value = value; } // set the minimum integer value the user can enter. // if entered value is inferior, input value will become equal to the set limit public void setMinValue(int value) { min_value = value; } // returns integer value or 0 if errorous value public int getValue() { try { return Integer.parseInt(this.getText().toString()); } catch (NumberFormatException exception) { return 0; } } } |
用法示例:
1 2 3 4 | final EditTextNumeric input = new EditTextNumeric(this); input.setMaxLength(5); input.setMaxValue(total_pages); input.setMinValue(1); |
适用于
由于goto10的观察,我将以下代码放在一起以防止在设置最大长度时丢失其他过滤器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * 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 }); } } |
1 2 3 4 5 6 7 8 | //Set Length filter. Restricting to 10 characters only editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)}); //Allowing only upper case characters editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()}); //Attaching multiple filters editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH), new InputFilter.AllCaps()}); |
我有这个问题,我认为我们缺少一个很好的解释方式,以编程方式执行此操作而不会丢失已设置的过滤器。
以XML格式设置长度:
正如所接受的答案正确陈述的那样,如果你想为EditText定义一个固定的长度,你将来不会进一步改变,只需在EditText XML中定义:
1 | android:maxLength="10" |
以编程方式设置长度
要以编程方式设置长度,您需要设置
Java的问题是:一旦你设置它,所有其他过滤器就会消失(例如maxLines,inputType等)。为避免丢失先前的过滤器,您需要获取之前应用的过滤器,添加maxLength,并将过滤器设置回EditText,如下所示:
1 2 3 4 5 | InputFilter[] editFilters = editText.getFilters(); InputFilter[] newFilters = new InputFilter[editFilters.length + 1]; System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length); newFilters[editFilters.length] = new InputFilter.LengthFilter(10); //the desired length editText.setFilters(newFilters); |
然而,Kotlin让每个人都更容易,你还需要将过滤器添加到现有的过滤器中,但是你可以通过简单的方法实现:
1 | editText.filters += InputFilter.LengthFilter(maxLength) |
XML
1 | android:maxLength="10" |
Java的:
1 2 3 4 5 | InputFilter[] editFilters = editText.getFilters(); InputFilter[] newFilters = new InputFilter[editFilters.length + 1]; System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length); newFilters[editFilters.length] = new InputFilter.LengthFilter(maxLength); editText.setFilters(newFilters); |
科特林:
1 | editText.filters += InputFilter.LengthFilter(maxLength) |
另一种可以实现此目的的方法是将以下定义添加到XML文件中:
1 2 3 4 5 6 7 8 | <EditText android:id="@+id/input" android:layout_width="0dp" android:layout_height="wrap_content" android:inputType="number" android:maxLength="6" android:hint="@string/hint_gov" android:layout_weight="1"/> |
这会将
从material.io,您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <com.google.android.material.textfield.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:counterEnabled="true" app:counterMaxLength="1000" app:passwordToggleEnabled="false"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/edit_text" android:hint="@string/description" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLength="1000" android:gravity="top|start" android:inputType="textMultiLine|textNoSuggestions"/> </com.google.android.material.textfield.TextInputLayout> |
您可以使用drawable配置密码EditText:
或者您可以使用/不使用计数器来限制文本长度:
相关性:
1 | implementation 'com.google.android.material:material:1.1.0-alpha02' |
XML
编程方式:
1 2 3 4 | int maxLength = 10; InputFilter[] filters = new InputFilter[1]; filters[0] = new InputFilter.LengthFilter(maxLength); yourEditText.setFilters(filters); |
注意:在内部,EditText&amp; TextView在XML中解析
请参阅:TextView.java#L1564
这很好......
这只会接受
它在xml中的简单方法:
1 | android:maxLength="4" |
如果你需要在xml编辑文本中设置4个字符,那么使用它
1 2 3 4 5 6 | <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的回答(下)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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 }); } } } |
我看到了很多很好的解决方案,但我想提供一个我认为更完整和用户友好的解决方案,其中包括:
1,限制长度。
2,如果输入更多,给予回调以触发你的祝酒词。
3,光标可以在中间或尾部。
4,用户可以通过粘贴字符串输入。
5,始终丢弃溢出输入并保留原点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 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',而不是原点高亮。我想有人解决这个问题。
您可以在EditText中使用
以编程方式尝试使用Java:
1 | myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)}); |