问题描述
我需要格式化输入货币用2十进制格式示例当用户输入2时它看起来是$ 2.00然后当用户输入2时它转换为$ 22.00 ...等
我接近类似的东西,当用户输入2时它转换为$ 0.02接下来2将是这样的$ 0.22
任何人都可以帮助我,谢谢你
public class MoneyTextWatcher implements TextWatcher {
private final WeakReference<EditText> editTextWeakReference;
public MoneyTextWatcher(EditText mEditText) {
editTextWeakReference = new WeakReference<EditText>(mEditText);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
EditText editTex = editTextWeakReference.get();
if(!s.toString().equals(editTex.getText())) {
editTex.removeTextChangedListener(this);
String cleanString = s.toString().replaceAll("[$,.]", "");
double parsed = Double.parseDouble(cleanString.replaceAll("[^\\d]", ""));
String formatted = NumberFormat.getCurrencyInstance().format((parsed / 100));
editTex.setText(formatted);
editTex.setSelection(formatted.length());
editTex.addTextChangedListener(this);
}
@Override
public void afterTextChanged(Editable s) {
}
}
}
1楼
我想你可以尝试以下方法:
布局:
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
/>
活动:
EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new NumberTextWatcher(editText, "#,###"));
使用文本观察器如下:
public class NumberTextWatcher implements TextWatcher {
private final DecimalFormat df;
private final DecimalFormat dfnd;
private final EditText et;
private boolean hasFractionalPart;
private int trailingZeroCount;
public NumberTextWatcher(EditText editText, String pattern) {
df = new DecimalFormat(pattern);
df.setDecimalSeparatorAlwaysShown(true);
dfnd = new DecimalFormat("#,###.00");
this.et = editText;
hasFractionalPart = false;
}
@Override
public void afterTextChanged(Editable s) {
et.removeTextChangedListener(this);
if (s != null && !s.toString().isEmpty()) {
try {
int inilen, endlen;
inilen = et.getText().length();
String v = s.toString().replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "").replace("$","");
Number n = df.parse(v);
int cp = et.getSelectionStart();
if (hasFractionalPart) {
StringBuilder trailingZeros = new StringBuilder();
while (trailingZeroCount-- > 0)
trailingZeros.append('0');
et.setText(df.format(n) + trailingZeros.toString());
} else {
et.setText(dfnd.format(n));
}
et.setText("$".concat(et.getText().toString()));
endlen = et.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel < et.getText().length()) {
et.setSelection(sel);
} else if (trailingZeroCount > -1) {
et.setSelection(et.getText().length() - 3);
} else {
et.setSelection(et.getText().length());
}
} catch (NumberFormatException | ParseException e) {
e.printStackTrace();
}
}
et.addTextChangedListener(this);
}
@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 index = s.toString().indexOf(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator()));
trailingZeroCount = 0;
if (index > -1) {
for (index++; index < s.length(); index++) {
if (s.charAt(index) == '0')
trailingZeroCount++;
else {
trailingZeroCount = 0;
}
}
hasFractionalPart = true;
} else {
hasFractionalPart = false;
}
}
}
2楼
保持用户输入的数字分开存放,因为如果使用edittext.text,则会遇到更多问题。
然后使用按需要格式化它。
对于第一个,也许这是用户开始编辑后立即将原始输入恢复到edittext的好方法,这样就可以避免编辑问题。
希望这可以帮助。
3楼
HI下面的代码会将每个数字转换为两位小数。 值应为数字,字符和特殊字符可能导致数字格式异常。 请根据需要处理。 谢谢
public static String formatDecimal(String value) {
DecimalFormat df = new DecimalFormat("#,###,##0.00");
return df.format(Double.valueOf(value));
}
4楼
我失去了不可思议的十个小时搜索或尝试代码。 所以我放弃了并为自己构建了这段代码。 它还没有修改但它有效,我来这里是为了帮助那些像我一样疯狂的人。
代码基本上是一个函数,它将放置textWatcher并将昏迷调整到正确的位置。 此代码适用于Kotlin。
首先,创建此功能:
fun CurrencyWatcher( editText:EditText) {
editText.addTextChangedListener(object : TextWatcher {
//this will prevent the loop
var changed: Boolean = false
override fun afterTextChanged(p0: Editable?) {
changed = false
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
editText.setSelection(p0.toString().length)
}
@SuppressLint("SetTextI18n")
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
if (!changed) {
changed = true
var str: String = p0.toString().replace(",", "").trim()
var element0: String = str.elementAt(0).toString()
var element1: String = "x"
var element2: String = "x"
var element3: String = "x"
var element4: String = "x"
var element5: String = "x"
var element6: String = "x"
//this variables will store each elements of the initials data for the case we need to move this numbers like: 0,01 to 0,11 or 0,11 to 0,01
if (str.length >= 2) {
element1 = str.elementAt(1).toString()
}
if (str.length >= 3) {
element2 = str.elementAt(2).toString()
}
editText.removeTextChangedListener(this)
//this first block of code will take care of the case
//where the number starts with 0 and needs to adjusta the 0 and the "," place
if (str.length == 1) {
str = "0,0" + str
editText.setText(str)
} else if (str.length <= 3 && str == "00") {
str = "0,00"
editText.setText(str)
editText.setSelection(str.length)
} else if (element0 == "0" && element1 == "0" && element2 == "0") {
str = str.replace("000", "")
str = "0,0" + str
editText.setText(str)
} else if (element0 == "0" && element1 == "0" && element2 != "0") {
str = str.replace("00", "")
str = "0," + str
editText.setText(str)
} else {
//This block of code works with the cases that we need to move the "," only because the value is bigger
//lets get the others elements
if (str.length >= 4) {
element3 = str.elementAt(3).toString()
}
if (str.length >= 5) {
element4 = str.elementAt(4).toString()
}
if (str.length >= 6) {
element5 = str.elementAt(5).toString()
}
if (str.length == 7) {
element6 = str.elementAt(6).toString()
}
if (str.length >= 4 && element0 != "0") {
val sb: StringBuilder = StringBuilder(str)
//set the coma in right place
sb.insert(str.length - 2, ",")
str = sb.toString()
}
//change the 0,11 to 1,11
if (str.length == 4 && element0 == "0") {
val sb: StringBuilder = StringBuilder(str)
//takes the initial 0 out
sb.deleteCharAt(0);
str = sb.toString()
val sb2: StringBuilder = StringBuilder(str)
sb2.insert(str.length - 2, ",")
str = sb2.toString()
}
//this will came up when its like 11,11 and the user delete one, so it will be now 1,11
if (str.length == 3 && element0 != "0") {
val sb: StringBuilder = StringBuilder(str)
sb.insert(str.length - 2, ",")
str = sb.toString()
}
//came up when its like 0,11 and the user delete one, output will be 0,01
if (str.length == 2 && element0 == "0") {
val sb: StringBuilder = StringBuilder(str)
//takes 0 out
sb.deleteCharAt(0);
str = sb.toString()
str = "0,0" + str
}
//came up when its 1,11 and the user delete, output will be 0,11
if (str.length == 2 && element0 != "0") {
val sb: StringBuilder = StringBuilder(str)
//retira o 0 da frente
sb.insert(0, "0,")
str = sb.toString()
}
editText.setText(str)
}
//places the selector at the end to increment the number
editText.setSelection(str.length)
editText.addTextChangedListener(this)
}
}
})
}
然后你用这种方式调用这个函数
val etVal:EditText = findViewById(R.id.etValue)
CurrencyWatcher(etVal)