Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

237
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!