Hi, I want to apply a visual transformation to a B...
# compose-android
k
Hi, I want to apply a visual transformation to a BasicTextField in Jetpack Compose. I've tried some code, but I'm facing several issues. For example, the cursor doesn't stay in the correct position, and when pressing backspace, the cursor moves to the wrong place.
I need the BasicTextField to always display a specific string (e.g., "ABC-") that cannot be removed, even with backspace or clear actions. Additionally, I want to limit the input and apply masking to format the text like this: "ABC-1234-2345-6366". Could someone help me implement this correctly?
Copy code
@Preview(showBackground = true)
 @Composable
 private fun SampleTextFieldView() {
     var textFieldValue by remember { mutableStateOf(TextFieldValue("ABC-")) }
     BasicFieldView(
         textFieldValue,
         onValueChange = { onValueChange ->
             val digitOnly = onValueChange.text.filter { it.isDigit() }
             val formattedString = buildString {
                 append("Abc-")
                 digitOnly.forEachIndexed { index, digit ->
                     if (index % 4 == 0 && index !=0 ){
                         append("-")
                     }
                     append(digit)
                 }
             }
             textFieldValue = onValueChange.copy(formattedString)
         }
     )
 }
 
 @Composable
 fun BasicFieldView(
     textFieldValue: TextFieldValue,
     onValueChange: (TextFieldValue) -> Unit,
 ) {
     Column(
         modifier = Modifier.fillMaxSize()
     ) {
         BasicTextField(
             modifier = Modifier.fillMaxWidth(),
             value = textFieldValue,
             onValueChange = {
                 onValueChange(it)
             },
         )
     }
 }
k
Thank you, I'll take a look now.
z
Better yet, use the new BasicTextField and avoid dealing with VT altogether
k
I'm using a new BasicTextField. Sorry what do you mean by VT ?
z
VisualTransformation. The new text field doesn't use it at all.
k
Could you please share any examples of how to use it without VisualTranformation.
z
this is the new field, and the docs on
OutputTransformation
include a sample
👀 1
k
Thank you so much I'll take a look
Hi zach, I tried below code and it's wokring fine.
Copy code
@Preview(showBackground = true)
@Composable
fun OutputDataPreview() {
    val state = rememberTextFieldState()
    Column(
        modifier = Modifier.fillMaxSize(),
    ) {
        BasicTextField(
            state = state,
            modifier = Modifier.fillMaxWidth(),
            inputTransformation = InputTransformation.maxLength(16)
                .then(DigitsOnlyTransformation),
            outputTransformation = GroupingOutputTransformation(4, "-"),
            decorator = { innerTextField ->
                Row {
                    Text(text = "ABC-")
                    innerTextField()
                }
            },
        )
    }
}

@Stable
data class GroupingOutputTransformation(
    private val groupSize: Int,
    private val groupDelimiter: String,
) : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        repeat((length - 1) / groupSize) {
            insert(it + (it + 1) * groupSize, groupDelimiter)
        }
    }
}

object DigitsOnlyTransformation : InputTransformation {
    override val keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)

    override fun TextFieldBuffer.transformInput() {
        if (!asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    }
}
I'm trying to reuse the same
BasicTextField
component in multiple places. I'm exploring how to use the
label
and
placeholder
properties, but I came across
TextFieldDefaults.DecorationBox
, which requires a
visualTransformation
. I want to apply a label animation decoration as well, but I'm not sure how to achieve this with the current setup. Could you help with this?
z
Ah yea material doesn’t support the new text field yet I guess
k
Are they planning to support?
z
Yes, I’d be surprised if it’s not already out in the alphas