How to add a scrollbar to a DropdownMenu in Jetpack Compose?

1k Views Asked by At

I'm using a Dropdown menu to fill a TextField. The problem is that the User may not know there are more items to scroll down to, and I'd like to implement a scroll-bar as a good solution to indicate scrollability.

TL;DR: Can't reliably attach any type of scroll listener to acquire real-time scroll position for DropdownMenu

@Composable
@OptIn(ExperimentalMaterialApi::class)
private fun DropDownTextField(
    selectedItem: Configuration?,
    items: List<Configuration>?,
    label: String,
    onItemSelected: (Configuration) -> Unit,
) {
    var isDropdownExpanded by remember {
        mutableStateOf(false)
    }

    ExposedDropdownMenuBox(expanded = isDropdownExpanded, onExpandedChange = {
        isDropdownExpanded = !isDropdownExpanded
    }) {
        OutlinedTextField(
            modifier = Modifier.fillMaxWidth(),
            textStyle = TextStyle.Default.copy(),
            value = selectedItem?.title ?: "",
            readOnly = true,
            onValueChange = {},
            label = {
                Text(text = label)
            },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(
                    expanded = isLanguageDropdownExpanded,
                )
            },
            keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Words),
        )

        DropdownMenu(
            expanded = isLanguageDropdownExpanded,
            onDismissRequest = {
                isLanguageDropdownExpanded = false
            },
            modifier = Modifier.background(color = Color.White).heightIn(min = 240.dp)
                .exposedDropdownSize(true),
        ) {
            items?.forEach { item ->
                DropdownMenuItem(onClick = {
                    onItemSelected(item)
                    isDropdownExpanded = false
                }) {
                    Row(
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(16.dp),
                    ) {
                        Text(text = item.title, color = LightTextGary)
                        if (selectedItem?.id == item.id) {
                            Icon(
                                painter = painterResource(id = R.drawable.ic_don),
                                ontentDescription = "selected",
                            )
                        }
                    }
                }
            }
        }
    }
}

BUT - no matter how I try, I cannot find a solution! There is no ready made scrollbar option for the component. To make things worse - "traditional" solutions like adding a .scrollable() or .draggable() listeners to the Modifier, to at least observe the scrolling position don't work Like it would on a simple Box() or Column() - because (I think) the actual Column() implemented by the component already has it's .verticalScroll() function utilized by it's modifier internaly. So by implementing my own scroll listener higher-up, it OR doesn't do anything, Or emits garbage, Or overrides the Menus scroll operation all together.

What am I doing wrong here? What am I missing?

I tried adopting solutions like this one for LazyColumn(), but as long as I can attach any reliable scroll listener, can't really progress to any other solution

0

There are 0 best solutions below