我们先来看下效果图:

直接上源码,这是公司项目里面的

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;/*** 带删除按钮的EditText 适配银行卡输入** @author huanghe*/
public class ClearEditText extends EditText {/*** 清楚按钮的图标*/private Drawable drawableClear;/*** 设置银行卡四位一空格*/int beforeTextLength = 0;int onTextLength = 0;boolean isChanged = false;int location = 0;private char[] tempChar;private StringBuffer buffer = new StringBuffer();int konggeNumberB = 0;private OnTextLengthListener mOnTextLengthListener;private boolean isBankNoType;private int maxLength;/*** 最大长度** @param maxLength*/public void setMaxLength(int maxLength) {this.maxLength = maxLength;invalidate();}/*** 银行卡类型** @param bankNoType*/public void setBankNoType(boolean bankNoType) {isBankNoType = bankNoType;invalidate();}public interface OnTextLengthListener {/*** 按钮可点击*/void onButtonEnable();/*** 按钮不可点击*/void onButtonUnEnable();}public void setOnTextLengthListener(OnTextLengthListener onTextLengthListener) {this.mOnTextLengthListener = onTextLengthListener;}public ClearEditText(Context context) {super(context);init(context, null);}public ClearEditText(Context context, AttributeSet attrs) {super(context, attrs);init(context, attrs);}public ClearEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context, attrs);}private void init(Context context, AttributeSet attrs) {// 获取自定义属性drawableClear = getResources().getDrawable(R.drawable.yhsh_ic_et_delete);updateIconClear();// 设置TextWatcher用于更新清除按钮显示状态addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {if (isBankNoType) {beforeTextLength = s.length();if (buffer.length() > 0) {buffer.delete(0, buffer.length());}konggeNumberB = 0;for (int i = 0; i < s.length(); i++) {if (s.charAt(i) == ' ') {konggeNumberB++;}}}}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {if (isBankNoType) {onTextLength = s.length();buffer.append(s.toString());if (onTextLength == beforeTextLength || onTextLength <= 3 || isChanged) {isChanged = false;return;}isChanged = true;}}@Overridepublic void afterTextChanged(Editable s) {updateIconClear();if (isChanged && isBankNoType) {location = getSelectionEnd();int index = 0;while (index < buffer.length()) {if (buffer.charAt(index) == ' ') {buffer.deleteCharAt(index);} else {index++;}}index = 0;int konggeNumberC = 0;while (index < buffer.length()) {if ((index == 4 || index == 9 || index == 14 || index == 19)) {buffer.insert(index, ' ');konggeNumberC++;}index++;}if (konggeNumberC > konggeNumberB) {location += (konggeNumberC - konggeNumberB);}tempChar = new char[buffer.length()];buffer.getChars(0, buffer.length(), tempChar, 0);String str = buffer.toString();if (location > str.length()) {location = str.length();} else if (location < 0) {location = 0;}setText(str);Editable etable = getText();Selection.setSelection(etable, location);isChanged = false;}sendLengthState(s, maxLength);}});setOnFocusChangeListener(new OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {updateIconClear();}});}/*** 发送editText的长度符合要求的状态** @param s* @param maxLength*/private void sendLengthState(Editable s, int maxLength) {int etLength = s.length();String etText = s.toString();if (maxLength == 23) {//银行卡if (etLength <= 23 && etLength >= 18) {etText.replaceAll(" ", "");dispatchEnable();} else {dispatchUnEnable();}} else if (maxLength == 18 && ValidateUtils.checkIdNumber(etText)) {//身份证if (maxLength == etLength) {dispatchEnable();} else {dispatchUnEnable();}} else if (maxLength != 0) {//纯数字if (maxLength == etLength) {dispatchEnable();} else {dispatchUnEnable();}} else {//姓名类if (etLength != 0) {dispatchEnable();} else {dispatchUnEnable();}}}private void dispatchEnable() {if (mOnTextLengthListener != null) {mOnTextLengthListener.onButtonEnable();}}private void dispatchUnEnable() {if (mOnTextLengthListener != null) {mOnTextLengthListener.onButtonUnEnable();}}@Overridepublic boolean onTouchEvent(MotionEvent event) {int xDown = (int) event.getX();if (event.getAction() == MotionEvent.ACTION_DOWN && xDown >= (getWidth() - getCompoundPaddingRight() * 2) && xDown < getWidth()) {// 清除按钮的点击范围 按钮自身大小 +-paddingsetText("");return false;}super.onTouchEvent(event);return true;}/*** 更新清除按钮图标显示*/private void updateIconClear() {// 获取设置好的drawableLeft、drawableTop、drawableRight、drawableBottomDrawable[] drawables = getCompoundDrawables();if (length() > 0 && isFocused()) {showIcon(true, drawables);} else {showIcon(false, drawables);}}private void showIcon(boolean isShow, Drawable[] drawables) {if (isShow) {setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], drawableClear,drawables[3]);} else {setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], null,drawables[3]);}}/*** 清空文本的方法*/public void clearText() {setText("");}
}

这是源码里面用到的工具类

import java.util.regex.Pattern;/**** 校验类*/public class ValidateUtils {private static final String PATTERN_IDCARD = "([0-9]{17}([0-9]|X|x))|([0-9]{15})";/*** 判断身份证位数或格式的正确性** @param idNumber* @return*/public static boolean checkIdNumber(String idNumber) {return Pattern.matches(PATTERN_IDCARD, idNumber);}}

Android开发之常用的自定义输入框之EditText相关推荐

  1. android自定义progressbar样式,Android开发中如何实现自定义ProgressBar的样式

    Android开发中如何实现自定义ProgressBar的样式 发布时间:2020-11-20 16:08:10 来源:亿速云 阅读:294 作者:Leah Android开发中如何实现自定义Prog ...

  2. 《Android开发艺术探索》自定义View中关于“HorizontalScrollViewEx”的改进

    在<Android开发艺术探索>一书中自定义View一节中提到了关于一个类似横向滑动List的自定义ViewGroup:HorizontalScrollViewEx.如果你使用过的话就会发 ...

  3. Android开发中实现带有删除图标的EditText输入框

    效果图如下: 备注:附带一个隐藏和显示密码的功能实现. activity_main.xml布局文件的代码如下: <?xml version="1.0" encoding=&q ...

  4. android什么控件能够输入多行文字,Android开发:文本控件详解——EditText(一)基本属性...

    一.简单实例: EditText输入的文字样式部分的属性,基本都是和TextView中的属性一样. 除此之外,EditText还有自己独有的属性. 二.基本属性: hint 输入框显示的提示文本 te ...

  5. Android 开发中常用小技巧

    TextView中的getTextSize返回值是以像素(px)为单位的, 而setTextSize()是以sp为单位的. 所以如果直接用返回的值来设置会出错,解决办法是 用setTextSize() ...

  6. Android开发,常用的终端命令

    1. ubuntu下配置环境anroid变量: 在终端执行 sudo gedit /etc/profile 打开文本编辑器,在最后追加#set android environment 2. 运行Ecl ...

  7. Android开发(Jetpack) 学习CameraX 自定义相机实现

    目录 一.CameraX和Camera2 二.CameraX的引入 三.自定义拍照 四.自定义视频录制 五.XML 配置 一.CameraX和Camera2 CameraX 是一个 Jetpack 库 ...

  8. Android开发中如何创建自定义对话框

    背景: 无论是Android,还是其他什么平台,对话框的主要形式都是弹出,或者我们可以说是一个在当前活动中打开的提示,来执行一些操作或实现一些功能. 你可以用一个对话框来问用户以确认一个行动,向用户通 ...

  9. NO.4 Android开发中常用框架及工具

    android-pulltorefresh 一个强大的拉动刷新开源项目,支持各种控件下拉刷新ListView.ViewPager.WevView.ExpandableListView.GridView ...

最新文章

  1. 在一台机器上搭建多个redis实例
  2. [翻译]Scott Mitchell 的ASP.NET 2.0数据教程之十三:在DetailsView控件中使用TemplateField...
  3. android中自适应布局教程,Android自适应布局设计技巧
  4. Alien 快速安装 Rippled 节点【Ubuntu】
  5. c监控进程发现未启动就启动进程_非常有用的16个Linux 服务器监控命令
  6. 利用条件GANs的pix2pix进化版:高分辨率图像合成和语义操作 | PaperDaily #23
  7. 读取数量不定的输入数据
  8. 黑客——技术的凝聚者???
  9. windows上的一些命令和工具
  10. php画图教程,php画图实例_PHP
  11. Java Web ServletResponse
  12. 你知道什么是 MySQL 的模糊查询?
  13. 最流行的轻量级php框架,GitHub - meolu/zan: zan 轻量级PHP微框架
  14. XMPP tigase 8.0 与 strophe.js 测试Web聊天服务/即时通信
  15. LTE:FDD、TDD下行峰值速率计算
  16. map组件如何展示marker的callout气泡
  17. 用html怎样实现抽奖效果,html5+css3实现抽奖活动的效果
  18. spring boot自动化配置
  19. 解决32G或64G的SD卡无法使用NOOBS安装树莓派的问题
  20. kali清理_白帽子教你Kali Linux:如何远程清除计算机日志信息防范被追踪?

热门文章

  1. vivado不识别HLS生成的IP解决方法
  2. java xor_java 简单xor加密
  3. linux oracle脚本编写,Linux 脚本编写基础(一)--语法
  4. 鼠标的计算机基础知识,2、使用鼠标--电脑基础知识
  5. typeScript模块四
  6. 博客园是个大金矿,管理员不挖掘有些可惜:给博客园提一些双赢的建议
  7. centos7.5 下LNMP搭建
  8. SQL Server 数据库的统计查询
  9. 在Linux上安装nginx时遇到的问题,真的好坑啊!!!!
  10. 第一阶段冲刺 第二天