Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

240
Vistas
Cómo evitar que Jetpack Compose ExposedDropdownMenuBox muestre el menú al desplazarse

Estoy tratando de usar ExposedDropdownMenuBox de Jetpack Compose, pero no puedo evitar que muestre el menú cuando me desplazo.

Por ejemplo, aquí está el código para replicar este problema:

 class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyApplicationTheme { Surface(color = MaterialTheme.colors.background) { Column( modifier = Modifier .padding(horizontal = 8.dp) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(8.dp) ) { repeat(20){ ExposedDropdownMenuSample() } } } } } } }

ExposedDropdownMenuSample se tomó de las muestras oficiales.

Este es un GIF que muestra el problema.

¿Cómo puedo evitar que esto suceda?

Este código usa la versión de composición 1.1.0-rc01 .

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Pude arreglar esto con este feo truco:

 private fun Modifier.cancelOnExpandedChangeIfScrolling() = pointerInput(Unit) { forEachGesture { coroutineScope { awaitPointerEventScope { var event: PointerEvent var startPosition = Offset.Unspecified var cancel = false do { event = awaitPointerEvent(PointerEventPass.Initial) if (startPosition == Offset.Unspecified) { startPosition = event.changes.first().position } val distance = startPosition.minus(event.changes.last().position).getDistance() cancel = distance > 10f || cancel } while ( !event.changes.all { it.changedToUp() } ) if (cancel) { event.changes.forEach { it.consumeAllChanges() } } } } } }

luego agréguelo a ExposedDropdownMenuBox como:

 ExposedDropdownMenuBox( expanded = expanded, onExpandedChange = { expanded = !expanded }, modifier = Modifier.cancelOnExpandedChangeIfScrolling() )

Entonces, ¿básicamente verifica si hubo un arrastre de más de 10 píxeles? y si es verdadero, consume los eventos para que no active onExpandedChange .

10 es solo un número mágico que funcionó bien para mis pruebas, pero parece demasiado bajo para un dispositivo de pantalla de alta resolución. Estoy seguro de que hay una mejor manera de calcular este número... ¿Tal vez alguien con más experiencia pueda ayudar con esto hasta que tengamos una solución adecuada?

over 4 years ago · Santiago Trujillo Denunciar

0

Encontré una solución un poco menos hacky:

Obtiene la información de si hay un desplazamiento en curso desde el estado de desplazamiento de la columna.

 val scrollState = rememberScrollState() val isScrolling = scrollState.isScrollInProgress Column( modifier = Modifier .padding(horizontal = 8.dp) .verticalScroll(scrollState), ... ) ...

En ExposedDropdownMenuBox , puede cambiar el oyente a

 onExpandedChange = { expanded = !expanded && !isScrolling },

=> El menú desplegable nunca se abre mientras se desplaza. También se cierra automáticamente tan pronto como comienza a desplazarse por la columna principal. Sin embargo, es posible desplazarse dentro del menú desplegable. Por supuesto, también puedes cambiarlo a algo como

 expanded = if (isScrolling) expanded else !expanded

Para dejar todo como está mientras se desplaza

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda