Skip to content

Instantly share code, notes, and snippets.

@moffpage
Created July 6, 2022 09:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moffpage/064bc33ae5ca309464506f8f93e3122a to your computer and use it in GitHub Desktop.
Save moffpage/064bc33ae5ca309464506f8f93e3122a to your computer and use it in GitHub Desktop.
import java.text.DecimalFormat
import androidx.core.text.isDigitsOnly
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation
private val String.isValidForFormatting get(): Boolean =
isNotBlank() && isDigitsOnly() && length <= 6
private fun String.formatToAmount(): String =
if (isValidForFormatting) {
DecimalFormat("#,##,###").format(this.toLong())
} else {
this
}
class CurrencyVisualTransformation(private val separator: Char = ' ') : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
val originalText = text.text
val formattedText = originalText.formatToAmount()
val annotatedText = AnnotatedString(text = formattedText)
val offsetMapping = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (originalText.isValidForFormatting) {
val separators = formattedText.count { character -> character == separator }
return when {
offset <= 1 -> offset
offset <= 3 -> if (separators >= 1) offset + 1 else offset
offset <= 5 -> if (separators == 2) offset + 2 else offset + 1
else -> 8
}
}
return offset
}
override fun transformedToOriginal(offset: Int): Int {
if (originalText.isValidForFormatting) {
val separators = formattedText.count { character -> character == separator }
return when (offset) {
8, 7 -> offset - 2
6 -> if (separators == 1) 5 else 4
5 -> if (separators == 1) 4 else if (separators == 2) 3 else offset
4, 3 -> if (separators >= 1) offset - 1 else offset
2 -> if (separators == 2) 1 else offset
else -> offset
}
}
return offset
}
}
return TransformedText(
text = annotatedText,
offsetMapping = offsetMapping
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment