Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

242
Visualizações
How to prevent Jetpack Compose ExposedDropdownMenuBox from showing menu when scrolling

I'm trying to use Jetpack Compose's ExposedDropdownMenuBox but I can't prevent it from showing the menu when scrolling.

For example, here's the code to replicate this problem:

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 was taken from the official samples.

This is a GIF showing the problem.

How can I prevent this from happening?

This code is using compose version 1.1.0-rc01.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

I was able to fix this with this ugly hack:

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() }
                }
            }
        }
    }
}

then add it to the ExposedDropdownMenuBox like:

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

So it basically checks if there was a drag for more than 10 pixels? and if true, consumes the events so it won't trigger the onExpandedChange.

10 is just a magic number that worked well for my tests, but it seems to be too low for a high res screen device. I'm sure there's a better way to calculate this number... Maybe someone more experienced can help with this until we have a proper fix?

over 4 years ago · Santiago Trujillo Relatório

0

I found a slightly less hacky workaround:

You get the info whether a scrolling is in progress from the scroll-state of the Column.

val scrollState = rememberScrollState()
val isScrolling = scrollState.isScrollInProgress

Column(
  modifier = Modifier
    .padding(horizontal = 8.dp)
    .verticalScroll(scrollState),
    ...
) ...

In the ExposedDropdownMenuBox you can then change the listener to

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

=> The dropdown is never opened while scrolling. It is also automatically closed as soon as you start scrolling in the main-column. However scrolling inside the dropdown is possible. Of course you can also cahnge it to something like

expanded = if (isScrolling) expanded else !expanded

To just leave everything like it is while scrolling

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda