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

How to create a TextField with underbar, without any background or border?


I'm trying to create a TextField, in Jetpack compose with an underbar but without any other border or background. How do I do this?

This is the code I'm currently using:

val query = remember {mutableStateOf("")}
        TextField(
        value = query.value,
            onValueChange = { newValue -> query.value = newValue },
            label={Text("Dummy", color = colorResource(id = R.color.fade_green))},
            textStyle = TextStyle(
                textAlign = TextAlign.Start,
                color = colorResource(id = R.color.fade_green),
                fontFamily = FontFamily(Font(R.font.poppins_regular)),
                fontSize = 14.sp,
            ),
            modifier = Modifier
                .padding(start = 30.dp).border(0.dp, Color.Red),
            colors = TextFieldDefaults.textFieldColors(
                backgroundColor = Color.Transparent
            )
            )

Solution

  • Starting with 1.2.0 you can use the BasicTextField + TextFieldDecorationBox.

    Something like:

        BasicTextField(
            value = text,
            onValueChange = {text = it},
            interactionSource = interactionSource,
            textStyle = mergedTextStyle,
            enabled = enabled,
            singleLine = true,
            modifier = Modifier
                .background(
                    color = White,  //Background color
                    shape = TextFieldDefaults.TextFieldShape
                )
                .indicatorLine(
                    enabled = enabled,
                    isError = false,
                    interactionSource = interactionSource,
                    colors = colors,
                    focusedIndicatorLineThickness =  2.dp, //width of the indicator
                    unfocusedIndicatorLineThickness = 2.dp
                )
            ) {
    
                TextFieldDefaults.TextFieldDecorationBox(
                    value = text,
                    enabled = enabled,
                    singleLine = true,
                    innerTextField = it,
                    visualTransformation = VisualTransformation.None,
                    interactionSource = interactionSource,
                    label = { Text("Label") },
                )
    
        }
    

    enter image description here


    With the 1.0.0 you can just use the colors attribute to define a Color.Transparent background.

    var text by remember { mutableStateOf("") }
    
    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        label = { Text("label") },
        colors = TextFieldDefaults.textFieldColors(
            backgroundColor = Color.Transparent,
            //Color of indicator = underbar
            focusedIndicatorColor = ....,
            unfocusedIndicatorColor = ....,
            disabledIndicatorColor = ....
        )
    )
    

    enter image description here enter image description here

    If you want to change the indicatorWidth currently there isn't a built-in parameter.

    You can use the .drawBehind modifier to draw a line. Something like:

    val interactionSource = remember { MutableInteractionSource() }
    val isFocused by interactionSource.collectIsFocusedAsState()
    
    val indicatorColor = if (isFocused) Color.Red else Color.Gray
    val indicatorWidth = 4.dp
    
    TextField(
        value = text,
        onValueChange = { 
           text = it },
        label={Text("Label")},
        interactionSource = interactionSource,
        modifier = Modifier
            .drawBehind {
                val strokeWidth = indicatorWidth.value * density
                val y = size.height - strokeWidth / 2
                drawLine(
                    indicatorColor,
                    Offset(0f, y),
                    Offset(size.width, y),
                    strokeWidth
                )
        },
        colors = TextFieldDefaults.textFieldColors(
            backgroundColor = Color.Transparent,
            focusedIndicatorColor =  Transparent,
            unfocusedIndicatorColor = Transparent,
            disabledIndicatorColor = Transparent
        )
    )
    

    enter image description here