Stay organized with collections
Save and categorize content based on your preferences.
This guide explains how to filter through a list of strings based on text input
in Jetpack Compose. Use this approach to dynamically update a list based on user
search queries.
Version compatibility
This implementation works with Compose versions 1.2.0 and higher.
Dependencies
Include the following dependencies in your build.gradle:
Filter a list based on text input
Together, the following snippets produce a list that updates in real time as the
user types. This example uses a ViewModel
to hold the list data and filtering logic, while the FilterTextView() function
creates the UI that updates automatically whenever the filter text changes.
classFilterTextViewModel:ViewModel(){privatevalitems=listOf("Cupcake","Donut","Eclair","Froyo","Gingerbread","Honeycomb","Ice Cream Sandwich")privateval_filteredItems=MutableStateFlow(items)varfilteredItems:StateFlow<List<String>>=_filteredItemsfunfilterText(input:String){// This filter returns the full items list when input is an empty string._filteredItems.value=items.filter{it.contains(input,ignoreCase=true)}}}
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2025-08-26 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-26 UTC."],[],[],null,["\u003cbr /\u003e\n\nThis guide explains how to filter through a list of strings based on text input\nin Jetpack Compose. Use this approach to dynamically update a list based on user\nsearch queries.\n\nVersion compatibility\n\nThis implementation works with Compose versions 1.2.0 and higher.\n\nDependencies\n\nInclude the following dependencies in your `build.gradle`:\n\nFilter a list based on text input\n\nTogether, the following snippets produce a list that updates in real time as the\nuser types. This example uses a [`ViewModel`](/reference/androidx/lifecycle/ViewModel)\nto hold the list data and filtering logic, while the `FilterTextView()` function\ncreates the UI that updates automatically whenever the filter text changes.\n\n\n```kotlin\nclass FilterTextViewModel : ViewModel() {\n private val items = listOf(\n \"Cupcake\",\n \"Donut\",\n \"Eclair\",\n \"Froyo\",\n \"Gingerbread\",\n \"Honeycomb\",\n \"Ice Cream Sandwich\"\n )\n\n private val _filteredItems = MutableStateFlow(items)\n var filteredItems: StateFlow\u003cList\u003cString\u003e\u003e = _filteredItems\n\n fun filterText(input: String) {\n // This filter returns the full items list when input is an empty string.\n _filteredItems.value = items.filter { it.contains(input, ignoreCase = true) }\n }\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/compose/snippets/src/main/java/com/example/compose/snippets/text/FilterText.kt#L42-L60\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- The `ViewModel` code abstracts the filtering work away from the composable.\n- The `ViewModel` holds both the original and filtered lists. It defines a list of items and a `MutableStateFlow` to hold the filtered items.\n- The `filterText` function filters the list based on the provided input string and updates the `filteredItems` state, which is passed back into the UI.\n\n\n```kotlin\n@Composable\nfun FilterTextView(modifier: Modifier = Modifier, viewModel: FilterTextViewModel = viewModel()) {\n val filteredItems by viewModel.filteredItems.collectAsStateWithLifecycle()\n var text by rememberSaveable { mutableStateOf(\"\") }\n\n Column(\n modifier = Modifier\n .fillMaxSize()\n .padding(all = 10.dp)\n ) {\n OutlinedTextField(\n value = text,\n onValueChange = {\n text = it\n viewModel.filterText(text)\n },\n label = { Text(\"Filter Text\") },\n modifier = Modifier.fillMaxWidth()\n )\n\n LazyColumn {\n items(\n count = filteredItems.size,\n key = { index -\u003e filteredItems[index] }\n ) {\n ListItem(\n headlineContent = { Text(filteredItems[it]) },\n modifier = Modifier\n .fillParentMaxWidth()\n .padding(10.dp)\n )\n }\n }\n }\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/compose/snippets/src/main/java/com/example/compose/snippets/text/FilterText.kt#L64-L98\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- Displays an [`OutlinedTextField`](/reference/kotlin/androidx/compose/material3/package-summary#OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue,kotlin.Function1,androidx.compose.ui.Modifier,kotlin.Boolean,kotlin.Boolean,androidx.compose.ui.text.TextStyle,kotlin.Function0,kotlin.Function0,kotlin.Function0,kotlin.Function0,kotlin.Function0,kotlin.Function0,kotlin.Function0,kotlin.Boolean,androidx.compose.ui.text.input.VisualTransformation,androidx.compose.foundation.text.KeyboardOptions,androidx.compose.foundation.text.KeyboardActions,kotlin.Boolean,kotlin.Int,kotlin.Int,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.ui.graphics.Shape,androidx.compose.material3.TextFieldColors)) for user input and a [`LazyColumn`](/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,androidx.compose.foundation.OverscrollEffect,kotlin.Function1)) to display the filtered list items.\n- Collects the `filteredItems` state flow from the `ViewModel` and converts it into a lifecycle-aware `State` object.\n - [`collectAsStateWithLifecycle`](/reference/kotlin/androidx/lifecycle/compose/package-summary#(kotlinx.coroutines.flow.StateFlow).collectAsStateWithLifecycle(androidx.lifecycle.Lifecycle,androidx.lifecycle.Lifecycle.State,kotlin.coroutines.CoroutineContext)) collects the latest value from the `StateFlow` and recomposes the UI when the value changes.\n- `text by rememberSaveable { mutableStateOf(\"\") }` creates a state variable `text` to hold the current text entered in the filter text field.\n - `rememberSaveable` preserves the value of text across configuration changes.\n - The `by` keyword delegates the value of text to the value property of the `MutableState` object.\n- `OutlinedTextField` calls the `filterText` function from the view model when text changes trigger the `onValueChange` callback.\n\nResult\n\n\u003cbr /\u003e\n\n**Figure 1.** A filtered list that updates as new text is entered.\n\n\u003cbr /\u003e\n\nCollections that contain this guide\n\nThis guide is part of these curated Quick Guide collections that cover\nbroader Android development goals: \n\nRequest user input \nLearn how to implement ways for users to interact with your app by entering text and using other means of input. \n[Quick guide collection](/develop/ui/compose/quick-guides/collections/request-user-input) \n\nHave questions or feedback \nGo to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts. \n[Go to FAQ](/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)"]]