Created
July 6, 2022 09:17
-
-
Save moffpage/064bc33ae5ca309464506f8f93e3122a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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