Android 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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • Android实现 EditText输入手机号空格功能

    Android EditText输入手机号空格 开发需求是在登录页面的手机EditText中间插入空格,让用户看起来方便点, 130 1234 4567,中间第4个数字和第5个数字空格前面加空格. 要求还有一点,就是除了输入要加入空格,从其他地方复制过来的电话号码,没有空格的,也要在粘贴后,自动补全空格. 思路:重写TextWatcher,每次EditText内容变化,都判断内容是否符合要求. @Override public void afterTextChanged(Editable s)

  • Android EditText每4位自动添加空格效果

    基本功能 刚拿到需求,很简单的一个功能,二话不说,很快就出来了: 完美!顺利上线! 没过几天领导拿着手机过来说:"这一堆数字在一起看着很费劲,像其他App一样,加个空格吧!" 于是就有了这个demo. 拓展功能 下面就来在基本功能上做拓展:每4位,自动添加空格. 看似很小的功能,在开发的过程中,遇到了非常多的问题与难点: EditText输入框监听死循环 输入框中的空格无法删除(删除又添加) 从中间删除一个数字产生的一系列问题 输入框光标位置的控制问题 之前踩坑的过程就不再赘述了,太心

  • Android EditTextView 实现带空格分隔的输入(电话号码,银行卡)

    电话号码输入框需求: 三位,七位后有空格 删除倒数第四,第八位会将空格也删除 使用TextWatcher When an object of a type is attached to an Editable, its methods will be called when the text is changed.就是说,只要是一个可编辑的文本设置了TextWatcher,当文本发生变化时,TextWatcher里的方法将会被调用. 其实不难,看了网上搜索到的例子,思路绕了点,这边做一份自己的记

  • Android EditText禁止输入空格和特殊字符

    有时候我们需要限制EditText输入的字符类型,如空格,特殊字符等,这时候我们可以使用系统提供的输入过滤器--InputFilter.具体实现如下: /** * 禁止EditText输入空格 * @param editText */ public static void setEditTextInhibitInputSpace(EditText editText){ InputFilter filter=new InputFilter() { @Override public CharSequ

  • Android之EditText控制禁止输入空格和回车

    1.EdiTtext输入框控制不能输入空格,给EditText添加一个addTextChangedListener监听,如果有空格split截取截取再for循环将截取后不包含空格的字符串数组重新排列这样这个字符串就不包含空格了,最后将这个字符串重新写入EditText,这时会出现一个问题就是光标会自动跳转到第一个位置,在onTextChanged中会有一个叫做start的变量他会传入在这个空格输入之前的光标位置,EditText.setSelection(int)来改变光标的位置具体位置. 具体

  • Android EditText追加空格、限制字符等方法示例

    前言 使用输入框时产品常常会有一些需求,比如123456789变成123-456-789或者限制一些字符的输入等等.很多时候都是网上搜索就完事了,但是每次都去搜索有点浪费时间,而且有些也不符合需求.所以自己写一篇,以后就可以吃老本了.

  • Android flutter Dio锁的巧妙实现方法示例

    正文 看Dio库源码的时候,发现其拦截器管理的逻辑处用到了一个Lock,这个Lock巧妙地利用了Completer和Future的机制来实现,记录一下. /// Add lock/unlock API for interceptors. class Lock { Future? _lock; late Completer _completer; /// 标识拦截器是否被上锁 bool get locked => _lock != null; /// Lock the interceptor. /

  • Android编程实现随机生成颜色的方法示例

    本文实例讲述了Android编程实现随机生成颜色的方法.分享给大家供大家参考,具体如下: 网上有个ColorPicker开源项目,选择颜色值.而在这里我想实现的是动态修改一个view的背景色. 开一个线程,每隔1s修改一次view的背景色. 我们知道在Android里设置一个view的背景色有 framelayout.setBackgroundColor(Color.parseColor("#"+arg0.obj)); 就是用android的Color类去解析一个带#号的十六进制色值.

  • Android开发之计算器GridLayout布局实现方法示例

    本文实例讲述了Android开发之计算器GridLayout布局实现方法.分享给大家供大家参考,具体如下: 运行效果: Demo 下载地址:https://github.com/LonglyWolf/Calculator 或者点击此处本站下载. 按钮布局实现: 一个Linearlayout 嵌套三个TextView 最下方的显示当前计算式.上面为先前的计算式. Gridview 网格布局排布按钮 <?xml version="1.0" encoding="utf-8&q

  • Android编程之菜单Menu的创建方法示例

    本文实例讲述了Android编程之菜单Menu的创建方法.分享给大家供大家参考,具体如下: 在res目录下的menu文件夹下创建一个main.xml文件,内容如下: <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="

  • Android编程之手机壁纸WallPaper设置方法示例

    本文实例讲述了Android编程之手机壁纸WallPaper设置方法.分享给大家供大家参考,具体如下: /** * Andorid设置手机屏幕的壁纸 * * @description: * @author ldm * @date 2016-5-4 下午3:08:56 */ public class SetWallpaperActivity extends Activity { // WallpaperManager类:系统壁纸管理.通过它可以获得当前壁纸以及设置指定图片作为系统壁纸. priva

  • Android编程绘图操作之弧形绘制方法示例

    本文实例讲述了Android编程绘图操作之弧形绘制方法.分享给大家供大家参考,具体如下: /** * 绘制弧形图案 * @description: * @author ldm * @date 2016-4-25 下午4:37:01 */ public class ArcsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedIns

  • Android编程之PopupWindow隐藏及显示方法示例(showAtLocation,showAsDropDown)

    本文实例讲述了Android编程之PopupWindow隐藏及显示方法.分享给大家供大家参考,具体如下: 前面分析了PopupWindow的用法(位置.动画.焦点)下面说说PopupWindow的如何隐藏.显示及显示位置(showAtLocation/showAsDropDown). 1.PopupWindow的隐藏 final PopupWindow window = mPageStatWin; if(null != window && window.isShowing()) { win

  • Android 使用PDF.js浏览pdf的方法示例

    Android的WebView做不到ios的WebView那样可以很方便的直接预览pdf文件.要实现利用WebView预览pdf我们可以使用谷歌文档服务: mWebView.loadUrl("http://docs.google.com/gviewembedded=true&url=" + pdfUrl); 这种方式国内网络环境是不用考虑的.当然也有替代的方案:我们可以使用mozilla开源的PDF.js. Github mozilla 官方demo 一 WebView设置:

随机推荐