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
0
投稿
猜你喜欢
- 桶排序桶排序是计数排序的升级,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过函数的某种映射关系,将待排序数组中
- 目录1、如果一个方法或变量是"private"访问级别,那么它的访问范围是:2、代码将打印?3、下面关于hibernat
- 服务限流,是指通过控制请求的速率或次数来达到保护服务的目的,在微服务中,我们通常会将它和熔断、降级搭配在一起使用,来避免瞬时的大量请求对系统
- (一) collection和collections这两者均位于java.util包下,不同的是:collection是一个集合接口,有Li
- RabbitMQ的一些基本组件Producer:消息的生产者Consumer:消息的消费者Broker:MQ服务器,管理队列、消息Messa
- 本想把练习题做了的结果放上来,不过发现附录是有答案的,就算了吧,自己做了没问题就行了哈。之前提到过,要是有朋友有想法,需要做小工具我可以帮忙
- 一、制作只含有字节码文件的jar包我们先来看只含有字节码文件,即只含有class文件的jar包怎么制作,这是最简单的形式1、最简单的jar包
- 如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求。Java有原生的API可用于发送HTTP请求,即
- java有两种类型的classload,一种是user-defined的,一种是jvm内置的bootstrap class loader,所
- 前言我们在 WPF 中使用绑定时可以使用 ElementName=Foo 这样的写法,并且还能够真的在运行时找到这个名称对应的对象,是因为
- 最近在学习ssh框架时,照着网上做了一个商城系统,之前在一些需要用户存在的操作中,都是在每一个action中写重复的代码,这样做现在想起来并
- 闲话不多说,直接上图。给大家讲讲我的编程思想吧。第一部分:沉浸式状态栏(API-Level 19, Android4.4 KitKat 之后
- 众所周知,在墙内开发很头疼的一件事就是Maven仓库的连接速度太慢。虽然对于很多互联网企业和大中型软件公司,建个镜像是分分钟的事。但对于个人
- 本文实例分析了JAVA反射机制。分享给大家供大家参考,具体如下:反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感
- 实现思路收集路径点集。平均采样路径点集。将路径点集转为 LineB。把 LineB 数据传给 Pat
- 如何调试Java程序?大家最开始学习Java,都会觉得IDE调试好高端有木有,其实很简单了。下文会尽量简单直观的教会你在Eclipse中调试
- Java类成员变量的默认值基本数据类型作为类的成员变量时可以不赋予初值,在方法中输出也不会报错。下面我们看看我们的八种数据类型的默认值是什么
- 定义Java修饰符:修饰符用来定义类、方法或者变量,通常放在语句的最前端。分类主要分为2类:访问控制修饰符非访问控制修饰符访问控制修饰符可以
- 1. 概述官方JavaDocsApi: java.awt.Component,java.awt.Containernull,绝对布局。绝对布
- 1.配置多个数据源多个数据源是指在同一个系统中,用户数据来自不同的表,在认证时,如果第一张表没有查找到用户,那就去第二张表中査询,依次类推。