【发布时间】:2022-11-24 04:51:05
【问题描述】:
如何实现也适用于小数的千位分隔符视觉转换。我找到了 Int 数字的千位分隔符视觉转换的实现,但问题是当我想将它用于十进制数字时,我必须控制小数分隔符的计数不超过 1 次。
【问题讨论】:
标签: android kotlin android-jetpack-compose android-compose-textfield
如何实现也适用于小数的千位分隔符视觉转换。我找到了 Int 数字的千位分隔符视觉转换的实现,但问题是当我想将它用于十进制数字时,我必须控制小数分隔符的计数不超过 1 次。
【问题讨论】:
标签: android kotlin android-jetpack-compose android-compose-textfield
您可以使用:
onValueChange使用正则表达式模式将允许的字符限制为十进制数的属性visualTransformation用千位分隔符格式化数字
就像是:
val pattern = remember { Regex("^\d*\.?\d*$") }
TextField(
value = text,
onValueChange = {
if (it.isEmpty() || it.matches(pattern)) {
text = it
}
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
visualTransformation = ThousandSeparato()
)
class ThousandSeparatorTransformation : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
val symbols = DecimalFormat().decimalFormatSymbols
val decimalSeparator = symbols.decimalSeparator
var outputText = ""
var integerPart = 0L
var decimalPart = ""
if (text.text.isNotEmpty()) {
val number = text.text.toDouble()
integerPart = number.toLong()
outputText += NumberFormat.getIntegerInstance().format(integerPart)
if (text.text.contains(decimalSeparator)) {
decimalPart = text.text.substring(text.text.indexOf(decimalSeparator))
if (decimalPart.isNotEmpty()) {
outputText += decimalPart
}
}
}
val numberOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
return outputText.length
}
override fun transformedToOriginal(offset: Int): Int {
return text.length
}
}
return TransformedText(
text = AnnotatedString(outputText),
offsetMapping = numberOffsetTranslator
)
}
}
对于这个OffsetMapping,光标在值的末尾保持静止。否则,您必须计算 thousandsSeparatorCount 并根据它确定偏移量。
【讨论】: