Android EditText追加空格、限制字符等方法示例
作者:denko 发布时间:2023-10-02 17:10:47
标签:edittext,限制,字符
前言
使用输入框时产品常常会有一些需求,比如123456789变成123-456-789或者限制一些字符的输入等等。很多时候都是网上搜索就完事了,但是每次都去搜索有点浪费时间,而且有些也不符合需求。所以自己写一篇,以后就可以吃老本了。😝
追加字符
借鉴博客EditText每4位自动添加空格
import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import com.ifreegroup.ebbly.lib_common.utils.AppLogUtil;
/**
* @Describe:自动添加占位符的输入框
* @Date: 2019/06/11
* @Author: dengkewu
* @Contact:
*/
public class PlaceHolderEditText extends android.support.v7.widget.AppCompatEditText {
//上次输入框中的内容
private String lastString;
//光标的位置
private int selectPosition;
//输入框内容改变监听
private TextChangeListener listener;
//追加字符
private String item = "-";
public PlaceHolderEditText(Context context) {
super(context);
initView();
}
public PlaceHolderEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public PlaceHolderEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
/**
* 当输入框内容改变时的回调
* @param s 改变后的字符串
* @param start 改变之后的光标下标
* @param before 删除了多少个字符
* @param count 添加了多少个字符
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//因为重新排序之后setText的存在
//会导致输入框的内容从0开始输入,这里是为了避免这种情况产生一系列问题
if (start == 0 && count > 1 && getSelectionStart() == 0) {
return;
}
String textTrim = getText().toString().trim();
if (TextUtils.isEmpty(textTrim)) {
return;
}
//如果 before >0 && count == 0,代表此次操作是删除操作
if (before > 0 && count == 0) {
selectPosition = start;
if (TextUtils.isEmpty(lastString)) {
return;
}
//将上次的字符串去空格 和 改变之后的字符串去空格 进行比较
//如果一致,代表本次操作删除的是空格
if (textTrim.equals(lastString.replaceAll(item, ""))) {
//帮助用户删除该删除的字符,而不是空格
StringBuilder stringBuilder = new StringBuilder(lastString);
stringBuilder.deleteCharAt(start - 1);
selectPosition = start - 1;
setText(stringBuilder.toString());
}
} else {
//此处代表是添加操作
//当光标位于空格之前,添加字符时,需要让光标跳过空格,再按照之前的逻辑计算光标位置
if ((start + count) % 5 == 0) {
selectPosition = start + count + 1;
} else {
selectPosition = start + count;
}
}
}
@Override
public void afterTextChanged(Editable s) {
//获取输入框中的内容,不可以去空格
String etContent = getText().toString();
if (TextUtils.isEmpty(etContent)) {
if (listener != null) {
listener.textChange("");
}
return;
}
//重新拼接字符串
String newContent = addSpaceByCredit(etContent);
//保存本次字符串数据
lastString = newContent;
//如果有改变,则重新填充
//防止EditText无限setText()产生死循环
if (!newContent.equals(etContent)) {
setText(newContent);
try {
//保证光标的位置
setSelection(selectPosition > newContent.length() ? newContent.length() : selectPosition);
} catch (Exception e) {
//刚好为限制字符的整数倍时添加空格后会出现越界的情况
//AppLogUtil.e("超过限制字符");
}
}
//触发回调内容
if (listener != null) {
listener.textChange(newContent);
}
}
});
}
/**
* 输入框内容回调,当输入框内容改变时会触发
*/
public interface TextChangeListener {
void textChange(String text);
}
public void setTextChangeListener(TextChangeListener listener) {
this.listener = listener;
}
/**
* 每4位添加一个空格
*
* @param content
* @return
*/
public String addSpaceByCredit(String content) {
if (TextUtils.isEmpty(content)) {
return "";
}
content = content.replaceAll(item, "");
if (TextUtils.isEmpty(content)) {
return "";
}
StringBuilder newString = new StringBuilder();
for (int i = 1; i <= content.length(); i++) {
if (i % 4 == 0 && i != content.length()) {
newString.append(content.charAt(i - 1) + item);
} else {
newString.append(content.charAt(i - 1));
}
}
return newString.toString();
}
/**
* 获取追加字符前输入内容
* @return
*/
public String getInputText() {
return getText().toString().replaceAll(item, "");
}
}
核心思路是在文本改变时获取到原字符串取出每一个字符添加上要追加的字符后返回字符串并重新setText。当然中间会有一些坑,比如光标位置、删除时空格要跳过以及删除后会再追加空格会造成死循环的问题。当然这里很多情况已经处理过了,如果有其他需求比如手机号码的111 1111 1111的形式可以修改addSpaceByCredit这个方法。
限制字符
借鉴博客Android EditText限制输入字符的5种实现方式
et_traveler_content.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) {
String editable = et_traveler_content.getText().toString();
String str = stringFilter(editable.toString());
if (!editable.equals(str)) {
et_traveler_content.setText(str);
//设置新的光标所在位置
et_traveler_content.setSelection(et_traveler_content.getText().toString().length());
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
public String stringFilter(String str) {
// 只允许字母、数字、英文空白字符
String regEx = "[^a-zA-Z0-9\\s]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("");
}
这里也是输入时做过滤然后重新setText。只要需要对正则表达式熟悉想做什么限制都可以。
MD效果
系统自带
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="15dp"
android:padding="0dp"
android:layout_centerVertical="true"
android:gravity="center_vertical">
<EditText
…… />
</android.support.design.widget.TextInputLayout>
只需要用TextInputLayout包裹一层便可以实现MD效果。
常用属性
1.明文、密文
if (isShowPwd) {
// 可视密码输入
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo
.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
} else {
// 非可视密码状态
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
}
2.默认不获取焦点
父容器设置(其实只要布局内有一个控件设置就可以)
android:focusableInTouchMode="true"
一些第三方库
MaterialEditText
Masked-Edittext
XEditText
来源:https://juejin.im/post/5cff6fdaf265da1bab29a516


猜你喜欢
- 使用WebSocketSharp自定义实现Web服务时,无法解析multipart/form-data请求的数据。通过查找资料,采用以下方式
- 人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中?这里浅谈Java中的栈和堆首先,将结论写在前
- 嵌入式开发中,由于产品的绑定、验证等逻辑限制比较严重,需要自己做一个上位机工具,来实现USB/BT通讯工具,实现如串口通讯、OTA升级等功能
- 使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删
- 在使用foreach时,collection属性值的三种情况:如果传入的参数类型为List时,collection的默认属性值为list,同
- 目录1、简介2、适用情况3、mybatis-plus前期准备(工程将以 H2 作为默认数据库进行演示)1、使用 Spring Initial
- Arrays.asList()方法的作用是将数组或一些元素转为集合,而你得到的集合并不是我们通常使用的List集合,而是Arrays里面的一
- 最近发现线上监控有个SQL调用量很大,但是方法的调用量不是很大,查看接口实现,发现接口是做了缓存操作的,使用Spring cache缓存注解
- 前言.如何设置设置使用的地方1.设置类注释模板代码/*** @author: lujie* @create: $date$* @descri
- 本文实例讲述了Android开发实现的IntentUtil跳转多功能工具类。分享给大家供大家参考,具体如下:说明:此工具类是本人开发中总结下
- 1. 你知道线程安全问题吗?线程安全问题:一般指在多线程模式下,多个线程对同一个共享数据进行操作时,第一个线程还没来得及更新共享数据,从而导
- 前言在实际工作中,重试机制是一个很常见的场景,比如:发送消息失败,下载网络文件失败等…,因为这些错误可能是网络波动造成
- ScrollConfiguration( behavior: NoScrollBehaviorWidget(),
- 经常进行图形界面设计的编程者肯定知道,控件在设计的时候才能随意拖动,运行的时候就不能拖动了.你肯定会问:运行时能随意拖动控件吗?答案是肯定的
- Tomcat 如何实现WebSocketWebSocket协议属于HTML5标准,越来越多浏览器已经原生支持WebSocket,它能让客户端
- 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。所以,标准C中的结构体是不允许包含成员函数的,当然C++中的结构体对此进行了扩展
- 圆形识别方案识别流程判断是否为封闭图形;根据圆的方程,取输入点集中的1/6、3/6、5/6处的三个点,求得圆的方程,获取圆心及半径;取点集中
- 一. 多任务和Task、启动模式Android 手机在早期,下方通常会内置三个实体的触摸按键,分别是:桌面、菜单、返回。大概在Android
- <?xml version="1.0" encoding="utf-8"?><Ed
- 前言Emmmm…最近在做项目的途中,有遇到一个方法需要接收的参数只有一个或者较少的时候就懒得写实体类去接收,使用spr