Cómo filtrar una lista mientras escribes

En esta guía, se explica cómo filtrar una lista de cadenas según la entrada de texto en Jetpack Compose. Usa este enfoque para actualizar de forma dinámica una lista según las consultas de búsqueda de los usuarios.

Compatibilidad de versiones

Esta implementación funciona con Compose 1.2.0 y versiones posteriores.

Dependencias

Incluye las siguientes dependencias en tu build.gradle:

Cómo filtrar una lista según la entrada de texto

En conjunto, los siguientes fragmentos producen una lista que se actualiza en tiempo real a medida que el usuario escribe. En este ejemplo, se usa un ViewModel para contener los datos de la lista y la lógica de filtrado, mientras que la función FilterTextView() crea la IU que se actualiza automáticamente cada vez que cambia el texto del filtro.

class FilterTextViewModel : ViewModel() {
    private val items = listOf(
        "Cupcake",
        "Donut",
        "Eclair",
        "Froyo",
        "Gingerbread",
        "Honeycomb",
        "Ice Cream Sandwich"
    )

    private val _filteredItems = MutableStateFlow(items)
    var filteredItems: StateFlow<List<String>> = _filteredItems

    fun filterText(input: String) {
        // This filter returns the full items list when input is an empty string.
        _filteredItems.value = items.filter { it.contains(input, ignoreCase = true) }
    }
}

Puntos clave sobre el código

  • El código ViewModel abstrae el trabajo de filtrado del elemento componible.
  • ViewModel contiene las listas originales y filtradas. Define una lista de elementos y un MutableStateFlow para contener los elementos filtrados.
  • La función filterText filtra la lista según la cadena de entrada proporcionada y actualiza el estado filteredItems, que se pasa a la IU.

@Composable
fun FilterTextView(modifier: Modifier = Modifier, viewModel: FilterTextViewModel = viewModel()) {
    val filteredItems by viewModel.filteredItems.collectAsStateWithLifecycle()
    var text by rememberSaveable { mutableStateOf("") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(all = 10.dp)
    ) {
        OutlinedTextField(
            value = text,
            onValueChange = {
                text = it
                viewModel.filterText(text)
            },
            label = { Text("Filter Text") },
            modifier = Modifier.fillMaxWidth()
        )

        LazyColumn {
            items(
                count = filteredItems.size,
                key = { index -> filteredItems[index] }
            ) {
                ListItem(
                    headlineContent = { Text(filteredItems[it]) },
                    modifier = Modifier
                        .fillParentMaxWidth()
                        .padding(10.dp)
                )
            }
        }
    }
}

Puntos clave sobre el código

  • Muestra un OutlinedTextField para la entrada del usuario y un LazyColumn para mostrar los elementos de la lista filtrada.
  • Recopila el flujo de estado filteredItems de ViewModel y lo convierte en un objeto State consciente del ciclo de vida.
  • text by rememberSaveable { mutableStateOf("") } crea una variable de estado text para contener el texto actual ingresado en el campo de texto del filtro.
    • rememberSaveable conserva el valor del texto en los cambios de configuración.
    • La palabra clave by delega el valor de texto a la propiedad de valor del objeto MutableState.
  • OutlinedTextField llama a la función filterText desde el modelo de vista cuando los cambios de texto activan la devolución de llamada onValueChange.

Resultado

Figura 1: Es una lista filtrada que se actualiza a medida que se ingresa texto nuevo.

Colecciones que contienen esta guía

Esta guía forma parte de estas colecciones de guías rápidas seleccionadas que abarcan objetivos más amplios de desarrollo de Android:

Aprende a implementar formas en las que los usuarios puedan interactuar con tu app ingresando texto y usando otros medios de entrada.

Tienes preguntas o comentarios

Ve a nuestra página de preguntas frecuentes para obtener información sobre las guías rápidas o comunícate con nosotros para contarnos tu opinión.