Search code examples
androidandroid-jetpack-composeandroid-compose-textfield

SWIFT or IFSC code formatter in android jetpack compose TextField editable


Ex: 23456-232

while typing above card number. we want to auto populate immediately - after 5th digit typed, then, user can enter last 3 digits.

how to achieve this in Jetpack compose in android.


Solution

  • You can write a custom VisualTransformation to format user entries in XXXXX-XXX format with

    class SwiftVisualTransformation : VisualTransformation {
        override fun filter(text: AnnotatedString): TransformedText {
            return swiftFilter(text)
        }
    }
    
    fun swiftFilter(text: AnnotatedString): TransformedText {
        val trimmed = if (text.text.length >= 8) text.text.substring(0..7) else text.text
        var out = ""
        for (i in trimmed.indices) {
            out += trimmed[i]
            if (i == 4) out += "-"
        }
    
        val swiftOffsetTranslator = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                if (offset <= 4) return offset
                if (offset <= 8) return offset + 1
                return 9
            }
    
            override fun transformedToOriginal(offset: Int): Int {
                if (offset <= 5) return offset
                if (offset <= 8) return offset - 1
                return 8
            }
        }
    
        return TransformedText(AnnotatedString(out), swiftOffsetTranslator)
    }
    

    And apply it

    @Preview
    @Composable
    fun SwiftVisualTransformationSample() {
    
        var swift by remember {
            mutableStateOf("")
        }
    
        OutlinedTextField(
            value = swift,
            label = { Text("Swift") },
            placeholder = { Text(text = "") },
            onValueChange = { newValue ->
                if (newValue.length <= 8) {
                    swift = newValue
                }
            },
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword),
            maxLines = 1,
            visualTransformation = SwiftVisualTransformation()
        )
    }