如何为EditText设置安全字符限制,避免粘贴超长度文本时闪退?
闪退原因
原生InputFilter.LengthFilter在处理超出长度的粘贴内容时,若内容包含富文本Span、或输入框同时配置了TextWatcher实时修改文本、开启了输入法联想功能,容易触发逻辑冲突,出现无堆栈的静默崩溃。
安全实现方案
方案1:自定义InputFilter替换系统LengthFilter(最推荐)
完全自主控制截断逻辑,避免原生实现的兼容问题,代码如下:
homeworkText = (EditText) getActivity().findViewById(R.id.homeworkText); // 最大输入字符数 int MAX_LENGTH = 300; InputFilter lengthFilter = new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { // 计算当前已有字符数+新增字符数 int keep = MAX_LENGTH - (dest.length() - (dend - dstart)); if (keep <= 0) { // 已经满了,直接拒绝新增内容 return ""; } else if (keep >= end - start) { // 新增长度未溢出,不拦截 return null; } else { // 只保留前keep个字符,自动截断超出部分 return source.subSequence(start, start + keep); } } }; homeworkText.setFilters(new InputFilter[]{lengthFilter});
方案2:搭配TextWatcher做兜底校验
如果已经在业务中使用了TextWatcher,可以在文本变化后做兜底修正,避免长度溢出:
homeworkText.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 (s.length() > 300) { // 直接截断到300字符 s.delete(300, s.length()); } } });
注意事项
- 不要同时在XML中配置
android:maxLength属性和代码中的InputFilter,重复配置会产生逻辑冲突 - 不需要富文本、表情输入的场景,可给EditText加上
android:inputType="textNoSuggestions"属性,关闭输入法联想,减少异常触发概率 - 若需要差异化计数(如一个中文/表情计2个字符),修改自定义Filter中的计数逻辑即可
内容的提问来源于stack exchange,提问作者Никита Попов
相关产品推荐
相关产品推荐

