作者:兜子

需求背景

我们需要做一个金额输入过滤器,限制小数点后只能输入两位数,以下解决方案,部分使用kotlin语言。

解决方案

  1. EditText的属性中先设置android:inputType=”numberDecimal”属性
  2. 新建一个类,继承DigitsKeyListener
  1. public class MoneyValueFilter extends DigitsKeyListener {
  2. public MoneyValueFilter() {
  3. super(false, true);
  4. }
  5. private int digits = 2;
  6. public MoneyValueFilter setDigits(int d) {
  7. digits = d;
  8. return this;
  9. }
  10. @Override
  11. public CharSequence filter(CharSequence source, int start, int end,
  12. Spanned dest, int dstart, int dend) {
  13. CharSequence out = super.filter(source, start, end, dest, dstart, dend);
  14. // if changed, replace the source
  15. if (out != null) {
  16. source = out;
  17. start = 0;
  18. end = out.length();
  19. }
  20. int len = end - start;
  21. // if deleting, source is empty
  22. // and deleting can't break anything
  23. if (len == 0) {
  24. return source;
  25. }
  26. //以点开始的时候,自动在前面添加0
  27. if(source.toString().equals(".") && dstart == 0){
  28. return "0.";
  29. }
  30. //如果起始位置为0,且第二位跟的不是".",则无法后续输入
  31. if(!source.toString().equals(".") && dest.toString().equals("0")){
  32. return "";
  33. }
  34. int dlen = dest.length();
  35. // Find the position of the decimal .
  36. for (int i = 0; i < dstart; i++) {
  37. if (dest.charAt(i) == '.') {
  38. // being here means, that a number has
  39. // been inserted after the dot
  40. // check if the amount of digits is right
  41. return (dlen-(i+1) + len > digits) ?
  42. "" :
  43. new SpannableStringBuilder(source, start, end);
  44. }
  45. }
  46. for (int i = start; i < end; ++i) {
  47. if (source.charAt(i) == '.') {
  48. // being here means, dot has been inserted
  49. // check if the amount of digits is right
  50. if ((dlen-dend) + (end-(i + 1)) > digits)
  51. return "";
  52. else
  53. break; // return new SpannableStringBuilder(source, start, end);
  54. }
  55. }
  56. // if the dot is after the inserted part,
  57. // nothing can break
  58. return new SpannableStringBuilder(source, start, end);
  59. }
  60. }
  1. 在代码中设置过滤器
  1. etAbleWithdrawMoney.filters = arrayOf(MoneyValueFilter())