文本更改时将数字转换为货币格式
Posted
技术标签:
【中文标题】文本更改时将数字转换为货币格式【英文标题】:converting numbers to currency format when text changes 【发布时间】:2017-12-05 08:28:31 【问题描述】:我将RxTextView.textChanges
用于EditText
,当用户输入EditText
的更改值以将数字转换为货币格式,如下所示:
1,000
但我看不到任何将数字转换为货币格式。
我正在使用来自:NumberFormat.getNumberInstance(Locale.US).format(productPrice);
我的代码如下:
Observable<CharSequence> observableDiscountPrice = RxTextView.textChanges(discountPriceEdittext);
observableDiscountPrice.map(new Function<CharSequence, Boolean>()
@Override
public Boolean apply(@io.reactivex.annotations.NonNull CharSequence charSequence) throws Exception
try
if (charSequence.length() > 0)
String pPrice = NumberFormat.getNumberInstance(Locale.US).format(charSequence.toString());
originalPriceEdittext.setText(String.valueOf(pPrice));
return true;
else
return false;
catch (Exception e)
return true;
).subscribe(new Subject<Boolean>()
@Override
public boolean hasObservers()
return false;
@Override
public boolean hasThrowable()
return false;
@Override
public boolean hasComplete()
return false;
@Override
public Throwable getThrowable()
return null;
@Override
protected void subscribeActual(Observer<? super Boolean> observer)
@Override
public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d)
@Override
public void onNext(@io.reactivex.annotations.NonNull Boolean aBoolean)
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e)
@Override
public void onComplete()
);
【问题讨论】:
你能检查你的NumberFormat
的导入吗?
【参考方案1】:
使用这个 TextWatcher 类:
public class NumberTextWatcherWithSeperator implements TextWatcher
private EditText editText;
public NumberTextWatcherWithSeperator(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.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);
catch (Exception ex)
ex.printStackTrace();
editText.addTextChangedListener(this);
private 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++;
和
yourEditText.addTextChangedListener(new NumberTextWatcherWithSeperator(yourEditText));
【讨论】:
@Alireza Noorali。此类在经常设备上存在错误。 @JoJoRoid:我已经在我的应用程序中使用了这个类,而且我的 Fabric crashlytics 报告中从来没有发生过一次崩溃。你试过这门课吗? 您的代码运行良好,但如何将小数位限制为 2【参考方案2】:看看https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
DecimalFormat myFormatter = new DecimalFormat("###,###.###");
String output = myFormatter.format(156456.673);
System.out.println(156456.673 + " " + "###,###.###" + " " + output);
// I/System.out: 156456.673 ###,###.### 156,456.673
【讨论】:
@Milos Lulic。我对此进行了测试,但这种方式在 textChanges 中有错误。【参考方案3】:我正在使用这个观察者做同样的事情:
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class CurrencyTextWatcher implements TextWatcher
private EditText ed;
private String lastText;
private boolean bDel = false;
private boolean bInsert = false;
private int pos;
public CurrencyTextWatcher(EditText ed)
this.ed = ed;
public static String getStringWithSeparator(long value)
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
String f = formatter.format(value);
return f;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
bDel = false;
bInsert = false;
if (before == 1 && count == 0)
bDel = true;
pos = start;
else if (before == 0 && count == 1)
bInsert = true;
pos = start;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
lastText = s.toString();
@Override
public void afterTextChanged(Editable s)
ed.removeTextChangedListener(this);
StringBuilder sb = new StringBuilder();
String text = s.toString();
for (int i = 0; i < text.length(); i++)
if ((text.charAt(i) >= 0x30 && text.charAt(i) <= 0x39) || text.charAt(i) == '.' || text.charAt(i) == ',')
sb.append(text.charAt(i));
if (!sb.toString().equals(s.toString()))
bDel = bInsert = false;
String newText = getFormattedString(sb.toString());
s.clear();
s.append(newText);
ed.addTextChangedListener(this);
if (bDel)
int idx = pos;
if (lastText.length() - 1 > newText.length())
idx--;
if (idx < 0)
idx = 0;
ed.setSelection(idx);
else if (bInsert)
int idx = pos + 1;
if (lastText.length() + 1 < newText.length())
idx++;
if (idx > newText.length())
idx = newText.length();
ed.setSelection(idx);
private String getFormattedString(String text)
String res = "";
try
String temp = text.replace(",", "");
long part1;
String part2 = "";
int dotIndex = temp.indexOf(".");
if (dotIndex >= 0)
part1 = Long.parseLong(temp.substring(0, dotIndex));
if (dotIndex + 1 <= temp.length())
part2 = temp.substring(dotIndex + 1).trim().replace(".", "").replace(",", "");
else
part1 = Long.parseLong(temp);
res = getStringWithSeparator(part1);
if (part2.length() > 0)
res += "." + part2;
else if (dotIndex >= 0)
res += ".";
catch (Exception ex)
ex.printStackTrace();
return res;
【讨论】:
【参考方案4】:如果你想和美元符号
fun multiply_two_numbers()
val x = etValOne.text.toString()
val y = etValTwo.text.toString()
val c = x.toDouble().times(y.toDouble())
//val c = (x.toDouble() * y.toDouble())
val df = DecimalFormat("$ "+"0.00")
df.roundingMode = RoundingMode.CEILING
df.format(c)
etANS.setText(df.format(c))
【讨论】:
以上是关于文本更改时将数字转换为货币格式的主要内容,如果未能解决你的问题,请参考以下文章