如何在EditText中input数字时自动添加千位分隔符

我创build一个转换器应用程序,我想设置EditText,以便当用户input要转换的数字时,应该自动添加一个千分号(,)实时添加到数字,一旦它增加3个数字….一千万,十亿等等,当擦除到4位以下时,数量恢复正常。 任何帮助? 谢谢。

Solutions Collecting From Web of "如何在EditText中input数字时自动添加千位分隔符"

您可以在TextWatcher使用String.format()格式说明符中的逗号可以解决这个问题。

这不适用于浮点input。 注意不要使用TextWatcher设置无限循环。

 public void afterTextChanged(Editable view) { String s = null; try { // The comma in the format specifier does the trick s = String.format("%,d", Long.parseLong(view.toString())); } catch (NumberFormatException e) { } // Set s back to the view after temporarily removing the text change listener } 

最后解决了这个问题

即使这个答案太晚了。 我已经研究了很多来完成任务为了得到正确的结果,但不能。 所以我终于解决了我们正在search的问题,并提供了这个答案给谷歌search者,以节省他们的search时间。

以下代码的特征

  1. EditText中放置千分隔符,因为它是文本更改。

  2. 在按下时间段(。)时自动添加0.首先。

  3. 在开始时忽略0input。

只需复制下面的类名

实现 TextWatcher的NumberTextWatcherForThousand

 import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.util.StringTokenizer; /** * Created by skb on 12/14/2015. */ public class NumberTextWatcherForThousand implements TextWatcher { EditText editText; public NumberTextWatcherForThousand(EditText editText) { this.editText = editText; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { try { editText.removeTextChangedListener(this); String value = editText.getText().toString(); if (value != null && !value.equals("")) { if(value.startsWith(".")){ editText.setText("0."); } if(value.startsWith("0") && !value.startsWith("0.")){ editText.setText(""); } String str = editText.getText().toString().replaceAll(",", ""); if (!value.equals("")) editText.setText(getDecimalFormattedString(str)); editText.setSelection(editText.getText().toString().length()); } editText.addTextChangedListener(this); return; } catch (Exception ex) { ex.printStackTrace(); editText.addTextChangedListener(this); } } public static String getDecimalFormattedString(String value) { StringTokenizer lst = new StringTokenizer(value, "."); String str1 = value; String str2 = ""; if (lst.countTokens() > 1) { str1 = lst.nextToken(); str2 = lst.nextToken(); } String str3 = ""; int i = 0; int j = -1 + str1.length(); if (str1.charAt( -1 + str1.length()) == '.') { j--; str3 = "."; } for (int k = j;; k--) { if (k < 0) { if (str2.length() > 0) str3 = str3 + "." + str2; return str3; } if (i == 3) { str3 = "," + str3; i = 0; } str3 = str1.charAt(k) + str3; i++; } } public static String trimCommaOfString(String string) { // String returnString; if(string.contains(",")){ return string.replace(",","");} else { return string; } } } 

在你的EditText上使用这个类如下

 editText.addTextChangedListener(new NumberTextWatcherForThousand(editText)); 

获得input为纯双文本

像这样使用相同类的trimCommaOfString方法

 NumberTextWatcherForThousand.trimCommaOfString(editText.getText().toString()) 

混帐

  public static String doubleToStringNoDecimal(double d) { DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);; formatter .applyPattern("#,###"); return formatter.format(d); } 

这个示例应用程序清楚地解构格式化数字。

要总结上面的链接,请使用TextWatcher并在afterTextChanged()方法中使用以下逻辑格式化EditText视图:

 @Override public void afterTextChanged(Editable s) { editText.removeTextChangedListener(this); try { String originalString = s.toString(); Long longval; if (originalString.contains(",")) { originalString = originalString.replaceAll(",", ""); } longval = Long.parseLong(originalString); DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US); formatter.applyPattern("#,###,###,###"); String formattedString = formatter.format(longval); //setting text after format to EditText editText.setText(formattedString); editText.setSelection(editText.getText().length()); } catch (NumberFormatException nfe) { nfe.printStackTrace(); } editText.addTextChangedListener(this); } 

这个解决scheme比其他答案有一些优势。 例如,即使编辑数字的开头或中间,也会保留用户的光标位置。 其他解决scheme总是将光标跳到数字的末尾 。 它处理小数点和整数 ,以及使用除以外字符的语言环境. 对于小数点分隔符,对于数千个分组分隔符。

 class SeparateThousands(val groupingSeparator: String, val decimalSeparator: String) : TextWatcher { private var busy = false override fun afterTextChanged(s: Editable?) { if (s != null && !busy) { busy = true var place = 0 val decimalPointIndex = s.indexOf(decimalSeparator) var i = if (decimalPointIndex == -1) { s.length - 1 } else { decimalPointIndex - 1 } while (i >= 0) { val c = s[i] if (c == ',') { s.delete(i, i + 1) } else { if (place % 3 == 0 && place != 0) { // insert a comma to the left of every 3rd digit (counting from right to // left) unless it's the leftmost digit s.insert(i + 1, groupingSeparator) } place++ } i-- } busy = false } } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } } 

然后在xml中:

  <EditText android:id="@+id/myNumberField" android:digits=",.0123456789" android:inputType="numberDecimal" .../> 

最后注册观察者:

 findViewById(R.id.myNumberField).addTextChangedListener( SeparateThousands(groupingSeparator, decimalSeparator)) 

处理 。 vs,在不同的语言环境中使用groupingSeparator和decimalSeparator,它们可以来自DecimalFormatSymbols或本地化的string。

你可以在你的程序中用很多方式使用这个代码,你给它一个string,并且把它们从右边分开,然后在那里放置空间。

 private String Spacer(String number){ StringBuilder strB = new StringBuilder(); strB.append(number); int Three = 0; for(int i=number.length();i>0;i--){ Three++; if(Three == 3){ strB.insert(i-1, " "); Three = 0; } } return strB.toString(); }// end Spacer() 

你可以改变一下,并使用它ontextchangelistener。 祝你好运

由于我有同样的问题,我决定find解决办法

find我的function,我希望它可以帮助人们find解决scheme

 securityDeposit.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable s) { // TODO Auto-generated method stub if (s.toString().trim().length() > 0) { int rentValue = Integer.parseInt(s.toString() .replaceAll(",", "")); StringBuffer rentVal = new StringBuffer(); if (rentValue > 10000000) { s.clear(); s.append("10,000,000"); } else { if (s.length() == 4) { char x[] = s.toString().toCharArray(); char y[] = new char[x.length + 1]; for (int z = 0; z < y.length; z++) { if (z == 1) { y[1] = ','; } else { if (z == 0) y[z] = x[z]; else { y[z] = x[z - 1]; } } } for (int z = 0; z < y.length; z++) { rentVal = rentVal.append(y[z]); } s.clear(); s.append(rentVal); } } } } }); 

这是我的ThousandNumberEditText

 public class ThousandNumberEditText extends android.support.v7.widget.AppCompatEditText { // TODO: 14/09/2017 change it if you want private static final int MAX_LENGTH = 20; private static final int MAX_DECIMAL = 3; public ThousandNumberEditText(Context context) { this(context, null); } public ThousandNumberEditText(Context context, AttributeSet attrs) { this(context, attrs, android.support.v7.appcompat.R.attr.editTextStyle); } public ThousandNumberEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { addTextChangedListener(new ThousandNumberTextWatcher(this)); setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); setFilters(new InputFilter[] { new InputFilter.LengthFilter(MAX_LENGTH) }); setHint("0"); // TODO: 14/09/2017 change it if you want } private static class ThousandNumberTextWatcher implements TextWatcher { private EditText mEditText; ThousandNumberTextWatcher(EditText editText) { mEditText = editText; } @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { String originalString = editable.toString(); String cleanString = originalString.replaceAll("[,]", ""); if (cleanString.isEmpty()) { return; } String formattedString = getFormatString(cleanString); mEditText.removeTextChangedListener(this); mEditText.setText(formattedString); mEditText.setSelection(mEditText.getText().length()); mEditText.addTextChangedListener(this); } /** * Return the format string */ private String getFormatString(String cleanString) { if (cleanString.contains(".")) { return formatDecimal(cleanString); } else { return formatInteger(cleanString); } } private String formatInteger(String str) { BigDecimal parsed = new BigDecimal(str); DecimalFormat formatter; formatter = new DecimalFormat("#,###"); return formatter.format(parsed); } private String formatDecimal(String str) { if (str.equals(".")) { return "."; } BigDecimal parsed = new BigDecimal(str); DecimalFormat formatter; formatter = new DecimalFormat("#,###." + getDecimalPattern(str)); //example patter #,###.00 return formatter.format(parsed); } /** * It will return suitable pattern for format decimal * For example: 10.2 -> return 0 | 10.23 -> return 00 | 10.235 -> return 000 */ private String getDecimalPattern(String str) { int decimalCount = str.length() - 1 - str.indexOf("."); StringBuilder decimalPattern = new StringBuilder(); for (int i = 0; i < decimalCount && i < MAX_DECIMAL; i++) { decimalPattern.append("0"); } return decimalPattern.toString(); } } } 

运用

 <.ThousandNumberEditText android:layout_width="match_parent" android:layout_height="wrap_content" /> 

我知道我很晚参加派对,但对未来的用户可能是非常有用的。 我的答案是Shree Krishna的答案的延伸。

改进:

  1. 成千上万的分隔符和十进制标记是区域识别,即相应地使用设备的Locale
  2. 在删除或添加中间元素后,光标位置也不会改变(在他的答案光标被重置为结尾)。
  3. 代码的整体质量得到了改善,特别是getDecimalFormattedString方法。

码:

  import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import java.text.DecimalFormat; /** * Created by srv_twry on 4/12/17. * Source: https://stackoverflow.com/a/34265406/137744 * The custom TextWatcher that automatically adds thousand separators in EditText. */ public class ThousandSeparatorTextWatcher implements TextWatcher { private DecimalFormat df; private EditText editText; private static String thousandSeparator; private static String decimalMarker; private int cursorPosition; public ThousandSeparatorTextWatcher(EditText editText) { this.editText = editText; df = new DecimalFormat("#,###.##"); df.setDecimalSeparatorAlwaysShown(true); thousandSeparator = Character.toString(df.getDecimalFormatSymbols().getGroupingSeparator()); decimalMarker = Character.toString(df.getDecimalFormatSymbols().getDecimalSeparator()); } @Override public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { cursorPosition = editText.getText().toString().length() - editText.getSelectionStart(); } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void afterTextChanged(Editable s) { try { editText.removeTextChangedListener(this); String value = editText.getText().toString(); if (value != null && !value.equals("")) { if (value.startsWith(decimalMarker)) { String text = "0" + decimalMarker; editText.setText(text); } if (value.startsWith("0") && !value.startsWith("0" + decimalMarker)) { int index = 0; while (index < value.length() && value.charAt(index) == '0') { index++; } String newValue = Character.toString(value.charAt(0)); if (index != 0) { newValue = value.charAt(0) + value.substring(index); } editText.setText(newValue); } String str = editText.getText().toString().replaceAll(thousandSeparator, ""); if (!value.equals("")) { editText.setText(getDecimalFormattedString(str)); } editText.setSelection(editText.getText().toString().length()); } //setting the cursor back to where it was editText.setSelection(editText.getText().toString().length() - cursorPosition); editText.addTextChangedListener(this); } catch (Exception ex) { ex.printStackTrace(); editText.addTextChangedListener(this); } } private static String getDecimalFormattedString(String value) { String[] splitValue = value.split("\\."); String beforeDecimal = value; String afterDecimal = null; String finalResult = ""; if (splitValue.length == 2) { beforeDecimal = splitValue[0]; afterDecimal = splitValue[1]; } int count = 0; for (int i = beforeDecimal.length() - 1; i >= 0 ; i--) { finalResult = beforeDecimal.charAt(i) + finalResult; count++; if (count == 3 && i > 0) { finalResult = thousandSeparator + finalResult; count = 0; } } if (afterDecimal != null) { finalResult = finalResult + decimalMarker + afterDecimal; } return finalResult; } /* * Returns the string after removing all the thousands separators. * */ public static String getOriginalString(String string) { return string.replace(thousandSeparator,""); } }