当前位置:网站首页>使用InputFilter限制EditText时踩坑及解决方案
使用InputFilter限制EditText时踩坑及解决方案
2022-07-03 03:11:00 【超努力的金蟾菇】
当我们想做EditText字符上的一些限制时,我们通常会用到InputFilter,通过重写里面的filter方法以做到限制长度的输入等,但是可能有心的同学会发现,在一些特定的情况下可能会发生字符取代覆盖的情况——比如我们用到特殊的输入法
//InputFilter接口,需要重写filter方法
public interface InputFilter
{
/** * @param source 输入的文字 * @param start 输入-0,删除-0 * @param end 输入-source文字的长度,删除-0 * @param dest 原先显示的内容 * @param dstart 输入-原光标位置,删除-光标删除结束位置 * @param dend 输入-原光标位置,删除-光标删除开始位置 * @return */
//主要重写这个方法
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend);
/** * This filter will capitalize all the lower case letters that are added * through edits. */
//接口内的静态内部类,,,输入小写转换成大写
public static class AllCaps implements InputFilter {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.isLowerCase(source.charAt(i))) {
char[] v = new char[end - start];
TextUtils.getChars(source, start, end, v, 0);
String s = new String(v).toUpperCase();
if (source instanceof Spanned) {
SpannableString sp = new SpannableString(s);
TextUtils.copySpansFrom((Spanned) source,
start, end, null, sp, 0);
return sp;
} else {
return s;
}
}
}
return null; // keep original
}
}
/** * This filter will constrain edits not to make the length of the text * greater than the specified length. */
// 长度过滤器,限制输入的长度
public static class LengthFilter implements InputFilter {
private final int mMax;
public LengthFilter(int max) {
mMax = max;
}
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
int dstart, int dend) {
int keep = mMax - (dest.length() - (dend - dstart));
if (keep <= 0) {
return ""; //主要问题出在这里,虽然inputfilter可以做输入过程中的长度限制,但是却不能对光标做任何的修改
} else if (keep >= end - start) {
return null; // keep original
} else {
keep += start;
if (Character.isHighSurrogate(source.charAt(keep - 1))) {
--keep;
if (keep == start) {
return "";
}
}
return source.subSequence(start, keep);
}
}
/** * @return the maximum length enforced by this input filter */
public int getMax() {
return mMax;
}
}
}
遇到这种与输入法相关的情况,我们就可以尝试另一种更灵活使用也更广泛的方法——Textwatcher,这个方法可以在输入时获取光标位置操作,更可以直接在输入时做出灵活的限制。具体操作可以参考下面一位大佬写的类。
package com.example.edittext;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
/** * 自定义MyTextWatcher类实现TextWatcher接口,并重写相关方法 * * @author 邹奇 * */
public class MyTextWatcher implements TextWatcher {
private int limit;// 字符个数限制
private EditText text;// 编辑框控件
private Context context;// 上下文对象
int cursor = 0;// 用来记录输入字符的时候光标的位置
int before_length;// 用来标注输入某一内容之前的编辑框中的内容的长度
public MyTextWatcher(EditText text, int limit,
Context context) {
this.limit = limit;
this.text = text;
this.context = context;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
before_length = s.length();
}
/** * s 编辑框中全部的内容 、start 编辑框中光标所在的位置(从0开始计算)、count 从手机的输入法中输入的字符个数 */
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
cursor = start;
// Log.e("此时光标的位置为", cursor + "");
}
@Override
public void afterTextChanged(Editable s) {
// 这里可以知道你已经输入的字数,大家可以自己根据需求来自定义文本控件实时的显示已经输入的字符个数
Log.e("此时你已经输入了", "" + s.length());
int after_length = s.length();// 输入内容后编辑框所有内容的总长度
// 如果字符添加后超过了限制的长度,那么就移除后面添加的那一部分,这个很关键
if (after_length > limit) {
// 比限制的最大数超出了多少字
int d_value = after_length - limit;
// 这时候从手机输入的字的个数
int d_num = after_length - before_length;
int st = cursor + (d_num - d_value);// 需要删除的超出部分的开始位置
int en = cursor + d_num;// 需要删除的超出部分的末尾位置
// 调用delete()方法将编辑框中超出部分的内容去掉
Editable s_new = s.delete(st, en);
// 给编辑框重新设置文本
text.setText(s_new.toString());
// 设置光标最后显示的位置为超出部分的开始位置,优化体验
text.setSelection(st);
// 弹出信息提示已超出字数限制
Toast.makeText(context, "已超出最大字数限制", Toast.LENGTH_SHORT).show();
}
}
}
最后附上两位大佬的代码链接(狗头保命
边栏推荐
- Thunderbolt Chrome extension caused the data returned by the server JS parsing page data exception
- Source code analysis | resource loading resources
- How to use asp Net MVC identity 2 change password authentication- How To Change Password Validation in ASP. Net MVC Identity 2?
- The XML file generated by labelimg is converted to VOC format
- 复选框的使用:全选,全不选,选一部分
- 模型转换onnx2engine
- Last update time of all sqlserver tables
- VS 2019配置tensorRT
- 文件重命名
- yii2 中andWhere多个or查询 orm条件
猜你喜欢

迅雷chrome扩展插件造成服务器返回的数据js解析页面数据异常

Vs Code configure virtual environment
![ASP. Net core 6 framework unveiling example demonstration [02]: application development based on routing, MVC and grpc](/img/cb/145937a27ef08050a370d5a255215a.jpg)
ASP. Net core 6 framework unveiling example demonstration [02]: application development based on routing, MVC and grpc

Check log4j problems using stain analysis
![MySQL practice 45 [global lock and table lock]](/img/23/fd58c185ae49ed6c04f1a696f10ff4.png)
MySQL practice 45 [global lock and table lock]

Vs 2019 configure tensorrt to generate engine

Kubernetes cluster log and efk architecture log scheme

用docker 连接mysql的过程

Vs 2019 configuration du moteur de génération de tensorrt

为什么线程崩溃不会导致 JVM 崩溃
随机推荐
Yiwen takes you to know ZigBee
Cron表达式介绍
How to implement append in tensor
@Accessors注解作用指定前缀遵守驼峰命名
内存泄漏工具VLD安装及使用
js根据树结构查找某个节点的下面的所有父节点或者子节点
Are there any recommended term life insurance products? I want to buy a term life insurance.
Installation and use of memory leak tool VLD
Thunderbolt Chrome extension caused the data returned by the server JS parsing page data exception
Edit and preview in the back pipe to get the value writing method of the form
Use cve-2021-43893 to delete files on the domain controller
Deep reinforcement learning for intelligent transportation systems: a survey paper reading notes
TCP 三次握手和四次挥手机制,TCP为什么要三次握手和四次挥手,TCP 连接建立失败处理机制
Change cell color in Excel using C - cell color changing in Excel using C
Vs Code configure virtual environment
Anhui University | small target tracking: large-scale data sets and baselines
MySQL practice 45 [SQL query and update execution process]
[C language] MD5 encryption for account password
Idea set method call ignore case
Kubernetes family container housekeeper pod online Q & A?