Whats the most sane way to allow editing a BigDeci...
# compose
z
Whats the most sane way to allow editing a BigDecimal value in a TextField with compose, while taking the current locale into account? 1. Different separators depending on the language: ',' or '.' 2. String.toBigDecimalOrNull() fails when using ',' 3. KeyboardType.Decimal allows inputting both separators, multiple times Do I just store the BigDecimal as a string value while editing, and calculate the actual value after the fact?
a
try using VisualTransformation
plus one 1
z
Thanks for the idea, do you mean so that the underlying text is the non-localized version of the BigDecimal, whereas what gets displayed is the localized one (using VisualTransformation)? If so, I have no idea how Id make that work in practice so if you have any idea, please let me know 😄
s
I had a similar use case a couple of weeks ago, but I had Double instead (with 2 decimal places). This one may help you https://medium.com/@banmarkovic/how-to-create-currency-amount-input-in-android-jetpack-compose-1bd11ba3b629
z
I would probably store a string that is only the digits, then add formatting via visual transformation. But that will probably be super tricky to get right with the current api. Should be a lot easier with the new text field APIs, especially the one I’m trying to land a basic version of before droidcon nyc 😅
a
If it comes to it, I think Zach will be trying to merge a change on stage
z
Live coding ftw
z
Thanks for all the suggestions! I saw your talk about BasicTextField2 earlier Zach and it seems super-promising, will tune in to this one as well. For now, Ive opted for this; converting to/from a localized BigDecimal when needed, and storing it as the raw input while editing:
Copy code
@Immutable
interface Converter<T> {

    fun value(
        input: String,
    ): T?

    fun format(
        value: T,
    ): String?
}
Copy code
@Stable
interface Property<out T> {

    var text: String?

    val value: T?
}

private class DefaultProperty<T>(
    initialInput: String?,
    converter: Converter<T>,
) : Property<T> {

    override var text by mutableStateOf(initialInput)

    override val value by derivedStateOf {
        text?.let(converter::value)
    }
}