0

I need to create a searchbar that looks like this (strictly compose): Without Text

With Text

Now i managed to get the one without text working, but i cannot get the cancel text to show up without bugs.

For example when using constraint row and some paddings i get effect like this Bug

link to the working code:

https://gist.github.com/piotrsedlak/d71da26299946ef6fc5125042e04a154

I also tried working with animateContentSize but that didnt really help.

1 Answer 1

2

I think this can be easily achieved using weight modifier. Conditionally adjust the weights and you'll get the desired effect. Here's a snippet for the same:

@Composable
fun DynamicToolbar() {
    var text by remember { mutableStateOf(TextFieldValue()) }
    val fieldWeight = if (text.text.isNotBlank()) 0.8f else 1f
    Row(modifier = Modifier.fillMaxWidth()
    ) {
        OutlinedTextField(
            value = text,
            onValueChange = { text = it },
            leadingIcon = { Icon(Icons.Default.Search, null, tint = Color.DarkGray) },
            trailingIcon = {
                if (text.text.isNotBlank()) {
                    Icon(
                        Icons.Default.Close,
                        null,
                        tint = Color.LightGray,
                        modifier = Modifier.clickable { text = text.copy("") }
                    )
                }
            },
            modifier = Modifier
                .weight(fieldWeight)
                .alignBy(FirstBaseline)
        )
        if (text.text.isNotBlank()) {
            TextButton(
                onClick = { },
                modifier = Modifier
                    .fillMaxWidth()
                    .weight(1 - fieldWeight)
                    .alignBy(FirstBaseline)
            ) {
                Text("Cancel")
            }
        }
    }
}

I'm using Compose 1.0.0-alpha11

PS: I fixed the baseline alignment problem as well (credits). Hope that helps.

Sign up to request clarification or add additional context in comments.

4 Comments

Solution is great, but as you can see in the screenshots, there cant be any "active" color when typing in text, i tried using your solution and setting activeColor to transparent, but then i lose the border and the indicator, do You maybe have a solution for that?
I thought the focus of this question was handling dynamic width for Row component. If you want to customise colors as well, I believe you should have a customised version of BasicTextField. I will try to put a solution for that later but that would be irrelevant to the title of this question.
Well in the gist link you can see that i put basictextfield inside the row, and it doesnt behave correctly (screenshots)
AFAIK, it's quite difficult to modify existing TextField APIs to build the above shown TextField. You can always copy paste internal classes/functions and modify the way you want but it'll impose a burden of maintaining that code as most of the TextField APIs are still experimental. I think CoreTextField function's decorationBox parameter will help you adjust border color and cursorColor is also there to tweak around.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.