博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EditText追加空格、限制字符等
阅读量:6968 次
发布时间:2019-06-27

本文共 7167 字,大约阅读时间需要 23 分钟。

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

追加字符

借鉴博客

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这个方法。

限制字符

借鉴博客

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效果

系统自带

复制代码

只需要用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"复制代码

一些第三方库


最开始坚持的地方,记录学习与生活的点点滴滴

转载于:https://juejin.im/post/5cff6fdaf265da1bab29a516

你可能感兴趣的文章
NOI元丹
查看>>
Androidn Notification的使用,解决找不到setLatestEventInfo方法
查看>>
如何改变eclipse控制台编码
查看>>
Python 闭包相关之late binding机制
查看>>
关于复制
查看>>
java AES
查看>>
实验五
查看>>
嵌入式Linux入门经典笔记
查看>>
leetcode29
查看>>
基于服务器的AAA作业(第二次)
查看>>
Objective-c——UI基础开发第十二天(相册展示)
查看>>
SQL中ISNULL的问题。
查看>>
利用map和stringstream数据流解题
查看>>
1.1.3 以类为单位的编程思想
查看>>
bzoj2440: [中山市选2011]完全平方数
查看>>
AC日记——中位数 洛谷 P1168
查看>>
Android 屏幕截图
查看>>
ubuntu 13.04 vim 的配置
查看>>
C++ 强制转换
查看>>
Python IDLE快捷键一览
查看>>