将数字字符串格式化为 2 个十进制双精度数,与数字字符串长度无关
Format a number string into 2 decimal double independent of the number string length
在使用 Kotlin 开发的 Android 应用程序中,有一个 EditText
只接受被视为美元的数字。输入需要格式化为2位小数,这样输入需要格式化如下
- 7 -> 0.07
- 73 -> 0.73
- 736 -> 7.36
已尝试使用输入过滤器。输入过滤器也用于限制最大值和单个小数输入条目。
editTextField.filters =
arrayOf(DecimalInputFilter())
class DecimalDigitsInputFilter() : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence? {}
}
无法格式化号码。可以根据规则限制输入。
editTextField.addTextChangedListener(object : TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
print("beforeTextChanged")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
print("onTextChanged")
val inputFormatter = DecimalFormat("0.00")
inputFormatter.isDecimalSeparatorAlwaysShown = true
inputFormatter.minimumFractionDigits = 2
editTextField.setText((s.toString()).format(inputFormatter))
}
override fun afterTextChanged(s: Editable?) {
print("afterTextChanged")
}
})
这也失败了。
我认为主要问题是您将文本设置到 TextWatcher
内部的 EditText
,这导致循环递归,然后是 stack-overflow。您应该更改包含在删除和再次添加 TextWatcher
中的文本。这是一个简单的解决方案:
editTextField.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
print("beforeTextChanged")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
print("onTextChanged")
val newValue = s.toString()
.takeIf { it.isNotBlank() }
?.replace(".", "")
?.toDouble() ?: 0.0
editTextField.let {
it.removeTextChangedListener(this)
it.setText(String.format("%.2f", newValue / 100))
it.setSelection(it.text?.length ?: 0)
it.addTextChangedListener(this)
}
}
override fun afterTextChanged(s: Editable?) {
print("afterTextChanged")
}
})
对于 Kotlin
fun roundOffDecimal(number: Double): String? {
val df = DecimalFormat("#,###,###.##")
df.roundingMode = RoundingMode.CEILING
return df.format(number)
}
RoundingMode.CEILNG 或 RoundingMode.FLOOR 用于将最后一位四舍五入。
#,###,###.##
根据您需要的位值类型和您想要的小数位数自定义此部分。
以上代码将显示类似于 3,250,250.12
的结果
在使用 Kotlin 开发的 Android 应用程序中,有一个 EditText
只接受被视为美元的数字。输入需要格式化为2位小数,这样输入需要格式化如下
- 7 -> 0.07
- 73 -> 0.73
- 736 -> 7.36
已尝试使用输入过滤器。输入过滤器也用于限制最大值和单个小数输入条目。
editTextField.filters =
arrayOf(DecimalInputFilter())
class DecimalDigitsInputFilter() : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence? {}
}
无法格式化号码。可以根据规则限制输入。
editTextField.addTextChangedListener(object : TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
print("beforeTextChanged")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
print("onTextChanged")
val inputFormatter = DecimalFormat("0.00")
inputFormatter.isDecimalSeparatorAlwaysShown = true
inputFormatter.minimumFractionDigits = 2
editTextField.setText((s.toString()).format(inputFormatter))
}
override fun afterTextChanged(s: Editable?) {
print("afterTextChanged")
}
})
这也失败了。
我认为主要问题是您将文本设置到 TextWatcher
内部的 EditText
,这导致循环递归,然后是 stack-overflow。您应该更改包含在删除和再次添加 TextWatcher
中的文本。这是一个简单的解决方案:
editTextField.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
print("beforeTextChanged")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
print("onTextChanged")
val newValue = s.toString()
.takeIf { it.isNotBlank() }
?.replace(".", "")
?.toDouble() ?: 0.0
editTextField.let {
it.removeTextChangedListener(this)
it.setText(String.format("%.2f", newValue / 100))
it.setSelection(it.text?.length ?: 0)
it.addTextChangedListener(this)
}
}
override fun afterTextChanged(s: Editable?) {
print("afterTextChanged")
}
})
对于 Kotlin
fun roundOffDecimal(number: Double): String? {
val df = DecimalFormat("#,###,###.##")
df.roundingMode = RoundingMode.CEILING
return df.format(number)
}
RoundingMode.CEILNG 或 RoundingMode.FLOOR 用于将最后一位四舍五入。
#,###,###.##
根据您需要的位值类型和您想要的小数位数自定义此部分。
以上代码将显示类似于 3,250,250.12
的结果