1

I'm trying to create a searching UI using Jetpack Compose. When the user would make an edit in the TextField, the search results matching the text query would appear in a floating list below the search field without moving other UI elements oh the screen. The mechanism can be compared to a browser's search engine suggestions when any text is written on the search field. Instead of suggestions I want to show the results. I have implemented everything for search. Just need the help to float search results so that other UI elements are not affected by it.

Following is the code of the composable for showing search field and the results.

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SearchCourse() {

    val viewModel = viewModel<MainViewModel>()
    val courses by viewModel.courses.collectAsState()
    val searchText by viewModel.searchText.collectAsState()

    val primaryColor = MaterialTheme.colorScheme.primary
    val secondaryColor = MaterialTheme.colorScheme.secondary
    val tertiaryColor = if (isSystemInDarkTheme()) Color.White else RoyalBlueTrad


    Column {
        
        TextField(
            value = searchText,
            onValueChange = viewModel::onSearchTextChange,
            modifier = Modifier.fillMaxWidth()
        )

        Box(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .animateContentSize(
                    animationSpec = tween(300, easing = LinearEasing)
                )
        ) {
            LazyColumn(
                Modifier
                    .scrollable(rememberScrollState(), Orientation.Vertical)
            ) {

                items(courses) {

                    Card(
                        modifier = Modifier
                            .padding(15.dp, 7.dp)
                            .fillMaxWidth(),
                        shape = RoundedCornerShape(10.dp),
                        colors = CardDefaults.cardColors(
                            containerColor = secondaryColor
                        )
                    ) {
                        Row(
                            modifier = Modifier
                                .fillMaxSize()
                                .padding(15.dp),
                            horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Text(
                                text = it.title,
                                modifier = Modifier.fillMaxWidth(0.7f),
                                color = primaryColor,
                                fontWeight = FontWeight.Light,
                                fontSize = 14.sp
                            )
                            Text(
                                text = it.code,
                                modifier = Modifier
                                    .wrapContentWidth()
                                    .background(primaryColor, RoundedCornerShape(5.dp))
                                    .padding(7.dp, 3.dp),
                                color = tertiaryColor,
                                fontWeight = FontWeight.Black,
                                fontSize = 14.sp
                            )
                        }
                    }
                }
            }
        }
    }
}

Since I have recently started learning Jetpack Compose I don't know much about floating items and couldn't really find any relevant solution on the internet either.

1 Answer 1

0

Material 3 provides a search bar and a docked search bar component.

var text by rememberSaveable { mutableStateOf("") }
var active by rememberSaveable { mutableStateOf(false) }
SearchBar(
   query = text,
   onQueryChange = { text = it },
   onSearch = { active = false },
   active = active,
   onActiveChange = {
       active = it
   }
) {
   // Search result shown when active
   LazyColumn(
       modifier = Modifier.fillMaxWidth(),
       contentPadding = PaddingValues(16.dp),
       verticalArrangement = Arrangement.spacedBy(4.dp)
   ) {
       items(4) { idx ->
         // Search result

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

3 Comments

I have tried this implementation with both SearchBar and DockedSearchBar. But when the SearchBar is activated it takes up the whole bottom space and pushes down the elements below. With DockedSearchBar and wrapContentHeight() on LazyColumn, it takes the space it needs for showing elements and still pushes down the elements below. How can I get the floating results with these that would be displayed on top like a dialog box without the pushing.
The values are hardcoded (I guess because that goes against M3's specs). You can wrap it inside a Box and then set the height, but you'll need to then add a padding to the rest of your components so they won't go behind the search... far from ideal but it might be the easiest way. Otherwise you can try using a TextField with a DropDownMenu which will show only if the user starts typing (don't forget to anchor the DropDownMenu to the TextField)
I have the same problem as @Syfur, the content below (behind) the SearchBar is pushed down as if content is anchored to the bottom of the expanded result window. Weird default behavior that makes little sense to the common use cases.

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.