[android]三步实现从右向左输入的金额输入的 EditText


1、概述

本渣渣在支付项目上遇到一个金额输入框。
开始觉得没啥,不就一小小输入框么有啥难的小case~小爷我分分钟弄出来……直到写的时候才发现这个金额输入框还是烦人的,硬是折腾了一下午,分分钟把自己搞秃头的节奏。
想想还是做个笔记吧~ 要不然等脑袋瓜子生锈了 ,下次在遇到想不出了, 就醉了~~~

功能描述##

金额输入框:功能便是很多POS设备上那样开始显示为: 0.00, 当输入数字时便会依次从右添加到输入框。例如依次输入123:输入1 == 0.01,继续输入2 == 0.12 ,随后输入3应该进位变为 3 == 1.23 。
也就是,实现从右向左输入并且保证有且只有俩位小数,至少有一位个位数。
这样的话,普通的输入框变没有办法实现了。
在这里就会遇到的问题大致便是是:
1、数字从右向左显示
2、保证小数位只有俩位,并至少有一位个位。
3、回退键处理(也就是回退时,从右开始删除,数字退位。例如:1.23 -->删除 == 0.12 , 0.12 -->删除 == 0.01 ,0.01 --> 删除 == 0.00 ,0.00 删除不变。)
4、长度无上限


2、思路##

开始的想法是,不就输入金额么,有啥难的,监听下输入的值然后把 用户输入的值 根据不同情况处理下咯额,怎么处理呢,嗯哼,把用户输完的数字拦截到,然后转化下类型。这样的话,用户输入1,把1/100,就是0.01了
用户输入12,12/100 就是 0.12,输入123就是1.23!哎呦妈呀,真™简单!好的除100。
然后就是…哎哎哎怎么小数位只有一位了…我的天,忘了数字有大小限制了。然后数字大了之后出来ABCDE……十六进制我的天……
哎哎,忘了还有删除键……删除乘个十?我也是天真。
一大堆的问题终结了我这个思路。忍不住吐槽自己一句MDZZ。。。



随后又想了几种其他的思路,什么把它变成字符串处理成数字的样子在进行转换,什么得到之前输入的值然后在后面补位……终归是无非达到想要的效果,最多就是很像但是bug一堆!

最后!小哥一个回光返照,额不,灵光一现~决定不在纠结于在“金额”二字上面,也就是我想直接拜托数字这个概念,然后分析了下。感觉如果可以通过一个算法将字符串进行处理 就不会有什么 16进制 ,转化出错,长度上限什么鬼问题了。
可是怎么通过字符串实现呢,分析了半天后,将重心放在了小数点上面“ . ”~
对头!就是这货,视觉上的数字输入和退位,可以看做是小数点的右移和左移。


① 举个输入例子就是:如果开始的字符串默认显示为0.00,此时,用户输入1,输入框中的字符串将会是0.001,我们将小数点向右移动就是00.01,然后在去掉头一个0,就变成了我们想要的0.01。同理,在0.01的基础上输入2,就会是0.012,小数点右移在去除头一个0,就是0.12。


②在举个删除的例子:如果此时的数字时显示为1.23,用户点击删除键,我们将小数点左移一位就是 .123,然后在前面添加个0,就变成了 0.123,去除第三位小数就变成了我们想要的结果 0.12。


这样的话避免了很多了问题,接下来就是实现了~


代码##

1、都说了是EditText,所以这个肯定必不可少哈~一个控制只能输入金额数字的输入框。

...

<EditText   
 android:id="@+id/edit_main"
 android:layout_width="match_parent"    
 android:layout_height="wrap_content"    
 android:inputType="numberDecimal"  
 android:numeric="decimal"    />

...

2、第二步在Activity里面找到editText然后监听他的文本输入。

 editText = (EditText) findViewById(R.id.edit_main);  
 editText.addTextChangedListener(new TextWatcher() {        
    private String  numberStr;       //定义一个字符串来得到处理后的金额
    @Override     
    public void beforeTextChanged(CharSequence s, int start, int 
                           count, int after) {  
                                                    } 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        
              int lenght = s.length();            
              Log.e("Sun", s + "====" + start + "=======" + before + "======" + count);     
              double number = 0.00;           //初始金额
              //第一次输入初始化 金额值
              if (lenght <= 1){            
              number = Double.parseDouble(s.toString());  
              number =number /100;//第一次 长度等于   
              numberStr = number + "";          
              }else {         
                       //之后的输入带入算法后将值设置给 金额值
                       if (s.toString().contains(".")){     
                       numberStr = getMoneyString(s.toString());  //这个方法看第三步  
                       }              
               }       
       }     
       @Override    
       public void afterTextChanged(Editable s) {      
                String aa = editText.getText().toString();   
                Toast.makeText(MainActivity.this, aa + "*****" + numberStr, Toast.LENGTH_SHORT).show();      
                 //在此判断输入框的值是否等于金额的值,如果不相同则赋值,如果不判断监听器将会出现死循环
                if (!TextUtils.isEmpty(editText.getText().toString()) && !editText.getText().toString().equals(numberStr)){              
                Toast.makeText(MainActivity.this,numberStr+"*****",Toast.LENGTH_SHORT).show();      
                editText.setText(numberStr);        //赋值到editText上
                editText.setSelection(numberStr.length()); //将光标定位到结尾       
          }           
      }      
  });

3、第三步写一个 处理金额的方法,就是重点方法☆☆☆☆☆

…

//定义一个处理字符串的方法
private String getMoneyString(String money){ 
     String overMoney = "";//结果  
     String[] pointBoth = money.split("\\.");//分隔点前点后    
     String beginOne = pointBoth[0].substring(pointBoth[0].length()-1);//前一位    
     String endOne = pointBoth[1].substring(0, 1);//后一位  
    //小数点前一位前面的字符串,小数点后一位后面 
     String beginPoint = pointBoth[0].substring(0,pointBoth[0].length()-1);   
     String endPoint = pointBoth[1].substring(1);   
     Log.e("Sun", pointBoth[0]+"==="+pointBoth[1] + "====" + beginOne + "=======" + endOne+"===>"+beginPoint+"=="+endPoint ); 
    //根据输入输出拼点  
     if (pointBoth[1].length()>2){//说明输入,小数点要往右移    
           overMoney=  pointBoth[0]+endOne+"."+endPoint;//拼接实现右移动    
     }else if (
           pointBoth[1].length()<2){//说明回退,小数点左移        
           overMoney = beginPoint+"."+beginOne+pointBoth[1];//拼接实现左移  
     }else {
             overMoney = money;   
        }   
   //去除点前面的0 或者补 0    
   String overLeft = overMoney.substring(0,overMoney.indexOf("."));//得到前面的字符串 
   Log.e("Sun","左邊:"+overLeft+"===去零前"+overMoney); 
   if (overLeft ==null || overLeft == ""||overLeft.length()<1){//如果没有就补零        
     overMoney = "0"+overMoney; 
   }else if(overLeft.length() > 1 && "0".equals(overLeft.subSequence(0, 1))){//如果前面有俩个零      
     overMoney = overMoney.substring(1);//去第一个0  
   }    
   Log.e("Sun","結果:"+overMoney);  
   return overMoney;
}

…

结尾#

  写到这里就 我笔记就写完啦~希望能帮到 有需求写 这个控件但是折腾了半天的小伙伴们~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容