0

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

J.K
  • 2,290
  • 1
  • 18
  • 29
Mardann
  • 1,953
  • 1
  • 16
  • 23
  • Might be possible with NestedScrollConnection, but I haven't tried. https://developer.android.com/reference/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollConnection – Jan Bína May 18 '23 at 11:44
  • Tried this. no luck. Something could be nested, but whatever it is, it's buried deep within the Dropdown component and not modifiable by me – Mardann May 18 '23 at 12:45
  • The point is that the scroll container doesn't have to be modifiable by you, you apply `.nestedScroll` modifier to the composable that you have under control, probably `DropdownMenu` in your case, and should receive all scroll events that happen inside... – Jan Bína May 18 '23 at 13:48
  • There is a current open issue due this error. https://issuetracker.google.com/issues/243812426 – Akhha8 Aug 03 '23 at 06:43

0 Answers0