Android金额输入控件
来源:互联网 发布:数据库权限管理制度 编辑:程序博客网 时间:2024/06/05 15:49
金额输入控件
最近在做一个金融的项目,里面有关于金额的判断和限制金额的输入,然后就发现了些问题。比如我们输入金额的时候肯定只能输入数字和点号,不能输入其他的字符;还有进行金额判断的时候很麻烦,比如要金额不能为0878787.98、.898或者0000000.98等等这样的。每次都要进行这样的判断很麻烦,又很耗时而且又容易出错,然后就在想能不能自己自定义一个控件来限制输入规范它,并且能将判断在内部处理。
首先我们要控制输入类型,这个很简单,我们只需要设置EditText的inputType类型为numberDecimal就行了。然后我们需要控制输入内容了,比如我们第一位输入的是为0,那么下一位必须为点号,不能继续输入数字,那么我们怎么实现这样的功能呢?
然后我们去看EditText的源码,发现没有。
然后我们发现EditText继承TextView,那么我们去看下TextView的源码
我们在这个发现了setFilters这个方法,感觉是,我们继续看下去
纯英文的,看不懂,没关系,我们百度看这个是不是我们需要找的
TextView和EditText中的setFilters方法说明
看来这个确实是我们要找的(在这篇文章中写的很清楚了,这里就不再说了),那么我们怎样设置规则呢?
好了,现在我们要开始设置规则了,那我们先考虑下,我们需要设置哪些规则?
- 如果以0开头
- 则下一位必须是点
- 0和点之间不能输入任何数字
- 如果不是0开头
- 不能将0放在字符串的第一位
- 第一位不能输入“.”
- 如果第一位为“.”,则点号后面不能继续输入
- 保留两位小数
- 验证删除等按键
将规则写清楚之后,我们就直接上代码吧
public class AmountFilter implements InputFilter {private final String TAG = "AmountFilter";Pattern mPattern;//正则匹配private static final int POINTER_AFTER_LENGTH = 2; //小数点后的位数private static final String POINTER = ".";private static final String ZERO = "0";public AmountFilter() { //正则表达式 mPattern = Pattern.compile("([0-9]|\\.)*");}/** * @param source 新输入的字符串 * @param start 新输入的字符串起始下标,一般为0 * @param end 新输入的字符串终点下标,一般为source长度-1 * @param dest 输入之前文本框内容 * @param dstart 原内容起始坐标,一般为0 * @param dend 原内容终点坐标,一般为dest长度-1 * @return 输入内容 */@Overridepublic CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { String sourceText = source.toString(); String destText = dest.toString(); //验证删除等按键 if (TextUtils.isEmpty(sourceText)) { return ""; } //如果是0开头,则下一位必须是点 if (destText.startsWith(ZERO)){ if (!TextUtils.equals(POINTER,source) && destText.length() == 1){ sourceText = ""; } //0和点之间不能输入任何数字 else if (destText.contains(POINTER)){ int point = destText.indexOf(POINTER); if (dstart <= point && dstart > 0){ sourceText = ""; } } else if (!destText.contains(POINTER) && dstart != 0 && destText.length() != 1){ sourceText = ""; } } //不能将0放在字符串的第一位 if (!TextUtils.isEmpty(destText) && dstart == 0 && TextUtils.equals(ZERO,sourceText) && !destText.startsWith(POINTER)){ sourceText = ""; } //第一位不能输入“.” if (TextUtils.isEmpty(destText) && TextUtils.equals(sourceText,POINTER)){ sourceText = ""; } //如果第一位为“.”,则点号后面不能继续输入 if (destText.startsWith(POINTER) && dstart != 0){ sourceText = ""; } //保留POINTER_AFTER_LENGTH位小数 if (!destText.contains(POINTER) && TextUtils.equals(POINTER,sourceText)){ int decimal = destText.length() - dstart; if (decimal > 2){ sourceText = ""; } }else if (destText.contains(POINTER)){ int point = destText.indexOf(POINTER); if (dstart > point && (destText.length() - point) >= 3){ sourceText = ""; } } String result = dest.subSequence(dstart, dend) + sourceText; return result;}
}
那么我们自定义一个AmountEditText
SuppressLint("AppCompatCustomView")public class AmountEditText extends EditText {private Context mContext;public AmountEditText(Context context) { super(context); init(context);}public AmountEditText(Context context, AttributeSet attrs) { super(context, attrs); init(context);}public AmountEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context);}private void init(Context context){ mContext = context;}@Overridepublic void setFilters(InputFilter[] filters) { filters = new InputFilter[]{new AmountFilter()}; super.setFilters(filters);}}
那么我们运行下看效果吧
可以看到只能输入两位小数,然后小数位就不能输入了。如果第一位输入为0,呢后以为只能输入点,输入其他的数字无法输入。那么到这里是不是已经完成了呢?不知道大家发现问题没有,有没有可能出现02342这种情况呢,理论上是不会出现的,我们现在试下
从图中可以看到是可能出现这种情况的,那么为什么能出现这种情况呢?这是因为InputFilter这能限制输入情况,已经存在的内容是没有办法控制的,那么我们就没有办法了吗?
当然这种情况也是有办法的。上面是对输入内容的限制,那么我们只要对输入结果做一个判断,检验输入结果是否符合规范就行了。
/** * 输入内容是否符合规则 * @return */public boolean isConformRules(){ String result = super.getText().toString(); if (TextUtils.isEmpty(result)){ return false; }else if (result.contains(".")){ if (result.startsWith(".")){ return false; }else if (result.startsWith("0")){ int indexZero = result.indexOf("0"); int indexPoint = result.indexOf("."); if (indexPoint - indexZero != 1){ return false; }else if (TextUtils.equals("0.",result)){ return false; } } }else if (!result.contains(".")){ if (result.startsWith("0")){ return false; } } return true;}
当我们输入完成之后,只需调用这个方法进行判断就行了。如果符合规则就返回true,不符合规则为false.那我们来检验一下
从图片中可以看到,已经完全ok的。最后,有时我们需要将金额转为分,即将结果*100,这里我们也设置了
/** * 获取设置倍数 * @return */public int getMultiple() { return Multiple;}/** * 设置金额倍数 * @param multiple */public void setMultiple(int multiple) { Multiple = multiple;}
只需在这里设置倍数即可,当然默认倍数为1,即原值不变
最后将Demo上传,需要的同学可以下载,有问题的话也可以在下方留言,谢谢!
阅读全文
0 0
- Android金额输入控件
- Android EditText输入金额
- 自定义控件-金额输入框
- Android实现EditText输入金额
- Android实现EditText输入金额
- 简陋的会计凭证金额输入控件
- 简陋的会计凭证金额输入控件(加强)
- android输入金额格式化文本框金额格式控制
- android输入金额格式化文本框金额格式控制
- android EditText设置只能输入金额
- android 金额输入框(小数点后两位)
- Android开发输金额EditText输入控制
- Android EditText 输入金额(小数点后两位)
- Android自定义View之金额输入EditText
- 简陋的会计凭证金额输入控件(再加强)
- Android金额输入框只允许输入小数点后两位
- Android 输入控件
- Android输入控件详解
- AS下导入另一个Library的Module
- Grid式的listview添加Header的方法
- 一篇不一样的docker原理解析
- UVA 458
- 累死你的不是工作,而是工作方式
- Android金额输入控件
- hdu6052 To my boyfriend (枚举计数)
- python Matplotlib 学习笔记(2)
- oracle创建表空间
- HDU -4775:Infinite Go
- 关于如何在highchart上获取后台返回的所需字段的值
- 理解asp.net保存页面状态值的原理
- linux 挂载目录
- Vue-resource拦截器判断token失效跳转