Android Moneyinput固定小数

你如何创build一个格式化input格式的edittext条目? 当用户input5时,我希望input看起来像“$ 0.05”,然后当他们input3时,input​​应该看起来像“$ 0.53”,最后input6,input应该看起来像“$ 5.36”。

Solutions Collecting From Web of "Android Moneyinput固定小数"

ninjasense完整的解决scheme基本上可行,但它有一些问题:

  1. 每当在“onTextChanged”处理程序中字段的数据被更改时,光标位置将重置为字段上的索引0,这在input货币值时有点烦人。
  2. 它使用浮动来格式化货币价值,这可能适得其反。

对于第一个问题,我还没有解决scheme,第二个这样的代码是这样工作的:

@Override public void onTextChanged(CharSequence s, int start, int before, int count) { if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$")) { String userInput= ""+s.toString().replaceAll("[^\\d]", ""); StringBuilder cashAmountBuilder = new StringBuilder(userInput); while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') { cashAmountBuilder.deleteCharAt(0); } while (cashAmountBuilder.length() < 3) { cashAmountBuilder.insert(0, '0'); } cashAmountBuilder.insert(cashAmountBuilder.length()-2, '.'); cashAmountBuilder.insert(0, '$'); cashAmountEdit.setText(cashAmountBuilder.toString()); } } 

build立Zds。

为了保持光标位于字段的末尾,使用这个。

 cashAmountEdit.setTextKeepState(cashAmountBuilder.toString()); Selection.setSelection(cashAmountEdit.getText(), cashAmountBuilder.toString().length()); 

你可以使用TextWatcher来做这种事情。

扩展TextWatcher: http ://d.android.com/reference/android/text/TextWatcher.html

 public class MyTextWatcher implements TextWatcher { public void afterTextChanged(Editable arg0) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } } 

然后将其添加到您的editText

 myEditText.addTextChangedListener(new MyTextWatcher()); 

我发现TextWatcher有点麻烦。 相反,您可以设置键监听器:

 setKeyListener(new CalculatorKeyListener()); // Must be called after setKeyListener(), otherwise is overridden setRawInputType(Configuration.KEYBOARD_12KEY); 

然后创build一个扩展NumberKeyListener的KeyListener:

 class CalculatorKeyListener extends NumberKeyListener { @Override public int getInputType() { return InputType.TYPE_CLASS_NUMBER; } @Override public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) { if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) { digitPressed(keyCode - KeyEvent.KEYCODE_0); } else if (keyCode == KeyEvent.KEYCODE_DEL) { deletePressed(); } return true; } @Override protected char[] getAcceptedChars() { return new char[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; } } 

然后您需要正确显示字符,但这并不困难; 只需跟踪美分,然后除或乘以10,并使用NumberFormat来获得正确的格式。

下面是我的完整解决scheme:

  tvValue.setRawInputType(Configuration.KEYBOARD_12KEY); tvValue.addTextChangedListener(new TextWatcher(){ @Override public void afterTextChanged(Editable arg0) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub // here i converted to string if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$")) { String userInput= ""+s.toString().replaceAll("[^\\d]", ""); Float in=Float.parseFloat(userInput); float percen = in/100; tvValue.setText("$"+percen); } } }); 

我做了这个,但没有十进制和点为英里,检查代码,并添加function,以支持小数。

  MyEditText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count){ if(s.toString().length() > 0){ MyEditText.removeTextChangedListener(this); String numbers = removeCharacters(s.toString()); int money = 0; try{ money = Integer.parseInt(numbers); } catch(Exception ex){ money = 0; } MyEditText.setText(getMoney(money)); //Set cursor on correct position int selection = start; if(count > 0){ selection++; if(MyEditText.getText().toString().length() == 2 || MyEditText.getText().toString().length() == 6 || MyEditText.getText().toString().length() == 10){ selection++; } } else{ if(MyEditText.getText().toString().length() == 4 || MyEditText.getText().toString().length() == 8){ selection--; } } if(selection > MyEditText.getText().toString().length()){ selection = MyEditText.getText().toString().length(); } MyEditText.setSelection(selection); MyEditText.addTextChangedListener(this); } if(s.toString().length() == 1 && count < 1 && start == 1){ MyEditText.removeTextChangedListener(this); MyEditText.setText(""); MyEditText.addTextChangedListener(this); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after){ } @Override public void afterTextChanged(Editable s) { } }); public String removeCharacters(String money){ int i=0; while (i<money.length()) { Character c = money.charAt(i); if (Character.isDigit(c) && c != '.') { i++; } else { money = money.replace(c.toString(), ""); } } return money; } public String getMoney(int value){ String money = "$"; NumberFormat numberFormatter; numberFormatter = NumberFormat.getNumberInstance(Locale.GERMAN); money += numberFormatter.format(value); return money; } 

这个答案是基于Zds的答案 (这反过来是基于ninjasense的答案 ),但是这应该解决光标位置问题:

 if(!text.matches("^\\$(\\d{1,2})(\\.\\d{2})?$")) { int originalCursorPosition = view.getSelectionStart(); int cursorOffset = 0; boolean cursorAtEnd = originalCursorPosition == text.length(); String userInput= ""+text.replaceAll("[^\\d]", ""); StringBuilder cashAmountBuilder = new StringBuilder(userInput); while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') { cashAmountBuilder.deleteCharAt(0); cursorOffset--; } while (cashAmountBuilder.length() < 3) { cashAmountBuilder.insert(0, '0'); cursorOffset++; } cashAmountBuilder.insert(cashAmountBuilder.length() - 2, '.'); cashAmountBuilder.insert(0, '$'); view.setText(cashAmountBuilder.toString()); view.setSelection(cursorAtEnd ? view.getText().length() : originalCursorPosition + cursorOffset); } 

笔记:

  • 以下是在TextWatcher.onTextChanged
  • 我正在使用一个不同的正则expression式比其他答案,它保持价格<$ 100
  • 'view'是editText,'text'是string的内容
  • 这已经为我使用的EditText maxLength为6(即$ 00.00)