2018-5-29 17:54:22 新增:
下面是网上找到的更优雅的实现方式,在原作的基础上添加了自动添加¥的功能:
public class CashierInputFilter implements InputFilter { Pattern mPattern; //输入的最大金额 private static final int MAX_VALUE = Integer.MAX_VALUE; //小数点后的位数 private static final int POINTER_LENGTH = 0; private static final String POINTER = "."; private static final String ZERO = "0"; public CashierInputFilter() { mPattern = Pattern.compile("([0-9]|\\.)*"); } /** * @param source 新输入的字符串 * @param start 新输入的字符串起始下标,一般为0 * @param end 新输入的字符串终点下标,一般为source长度-1 * @param dest 输入之前文本框内容 * @param dstart 原内容起始坐标,一般为0 * @param dend 原内容终点坐标,一般为dest长度-1 * @return 输入内容 */ @Override public 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 ""; } Matcher matcher = mPattern.matcher(source); //已经输入小数点的情况下,只能输入数字 if(destText.contains(POINTER)) { if (!matcher.matches()) { return ""; } else { if (POINTER.equals(source.toString())) { //只能输入一个小数点 return ""; } } //验证小数点精度,保证小数点后只能输入两位 int index = destText.indexOf(POINTER); int length = dend - index; if (length > POINTER_LENGTH) { return dest.subSequence(dstart, dend); } } else { /** * 没有输入小数点的情况下,只能输入小数点和数字 * 1. 首位不能输入小数点 * 2. 如果首位输入0,则接下来只能输入小数点了 */ if (!matcher.matches()) { return ""; } else { if ((POINTER.equals(source.toString())) && TextUtils.isEmpty(destText)) { //首位不能输入小数点 return ""; } else if (!POINTER.equals(source.toString()) && ZERO.equals(destText)) { //如果首位输入0,接下来只能输入小数点 return ""; } } } //验证输入金额的大小 String result = destText + sourceText; result =result.replaceAll("¥",""); double sumText = Double.parseDouble(result); if (sumText > MAX_VALUE) { return dest.subSequence(dstart, dend); } if (destText.startsWith("¥")) { return dest.subSequence(dstart, dend) + sourceText; } else { return "¥"+dest.subSequence(dstart, dend) + sourceText; } } }在实现自动添加¥的功能的时候还发现在限制
android:inputType="numberDecimal"的时候,数字之外的字符是不会显示的,¥也不会显示,不限制输入类型为小数呢也不符合需求,后来经偶像大牛大飞哥的提醒.在xml中
android:digits="0123456789.¥"
再加入digits的限制,问题就解决了,大飞哥是真的强.
2018-8-24 11:01:46 新增支持最大最小值限定和负数:
public class CashierInputFilter implements InputFilter { //小数点后的位数 private static final int POINTER_LENGTH = 2; private static final String POINTER = "."; private static final String ZERO = "0"; private Pattern mPattern; //输入的最大金额 private double mMaxValue = Double.MAX_VALUE; private double mMinValue = 0f; public CashierInputFilter(double maxValue) { mMaxValue = maxValue; init(); } public void init() { if (mMinValue == 0) { mPattern = Pattern.compile("([0-9]|\\.)*"); } else { mPattern = Pattern.compile("([-]?[0-9]?|\\.)*"); } } public CashierInputFilter(double maxValue, double minValue) { mMaxValue = maxValue; mMinValue = minValue; init(); } /** * @param source 新输入的字符串 * @param start 新输入的字符串起始下标,一般为0 * @param end 新输入的字符串终点下标,一般为source长度-1 * @param dest 输入之前文本框内容 * @param dstart 原内容起始坐标,一般为0 * @param dend 原内容终点坐标,一般为dest长度-1 * @return 输入内容 */ @Override public 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 ""; } Matcher matcher = mPattern.matcher(source); //已经输入小数点的情况下,只能输入数字 if (destText.contains(POINTER)) { if (!matcher.matches()) { return ""; } else { if (POINTER.equals(source.toString())) { //只能输入一个小数点 return ""; } } //验证小数点精度,保证小数点后只能输入两位 int index = destText.indexOf(POINTER); int length = dend - index; if (length > POINTER_LENGTH) { return dest.subSequence(dstart, dend); } } else { /** * 没有输入小数点的情况下,只能输入小数点和数字 * 1. 首位不能输入小数点 * 2. 如果首位输入0,则接下来只能输入小数点了 */ if (!matcher.matches()) { return ""; } else { if ((POINTER.equals(source.toString())) && TextUtils.isEmpty(destText)) { //首位不能输入小数点 return ""; } else if (!POINTER.equals(source.toString()) && ZERO.equals(destText)) { //如果首位输入0,接下来只能输入小数点 return ""; } } } //验证输入金额的大小 String result = destText + sourceText; if (mMinValue < 0 && "-".equals(result)) { return result; } double sumText = Double.parseDouble(result); if (sumText > mMaxValue||sumText<mMinValue) { return dest.subSequence(dstart, dend); } return dest.subSequence(dstart, dend) + sourceText; } }