androiddrop-down-menuandroid-jetpack-composeandroid-jetpack-compose-material3

Can't see the content of the drop down menu


I am trying to make a Ui component, so when I click a button "attachments" a drop down menu should pop up and show the drop down menu items. I want to make the drop down menu to pop up as a "drop up" menu, that means on click of icon, instead of showing menu downwards I want to show menu upwards. But when I made it, it is not showing the items inside the drop down menu.

These are the code pieces of my drop down menu , and where it is been used->

@Composable
fun AttachmentsDropDownMenu(
    modifier: Modifier = Modifier,
    state: MessageScreenState,
    action: (MessageScreenAction) -> Unit
){

    val buttonHeight = 48.dp // Height of your button
    val dropdownHeight = 120.dp // Approximate height of your dropdown


        // Dropdown Menu
        DropdownMenu(
            expanded = state.showAttachmentDropDown,
            onDismissRequest = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
            modifier = modifier.offset(y = -dropdownHeight - buttonHeight) // Shift above the button
        ) {
            DropdownMenuItem(
                onClick = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
                text = { Text(text = "Photo")}
            )

            DropdownMenuItem(
                onClick = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
                text = { Text(text = "Video")}
            )

            DropdownMenuItem(
                onClick = { action(MessageScreenAction.onHideAttachmentDropDownMenu)},
                text = { Text(text = "Document")}
            )
        }


}

Drop down menu is used here :

@Composable
fun MessagesScreen(
    modifier: Modifier = Modifier,
    id: Int,
    state: MessageScreenState,
    onActions: (MessageScreenAction) -> Unit
){
    Scaffold(
        modifier = modifier
            .fillMaxSize()
    ) {innerPadding->
        Column (
            modifier = Modifier
                .padding(innerPadding)
        ){
            LazyColumn(
                modifier = Modifier
                    .fillMaxSize()
                    .weight(1f)
            ) {
                items((1..100).toList()){
                    Text(text = "item ${it}")

                }

            }

            //For reply
            Row (
                modifier = Modifier
                    .padding(8.dp)
                    .fillMaxWidth()
                    .wrapContentHeight(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ){
                Row (
                    modifier = Modifier
                        .height(50.dp)
                        .weight(1f)
                        .clip(RoundedCornerShape(32.dp))
                        .background(Color.LightGray),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ){
                    Icon(
                        imageVector = ImageVector.vectorResource(id = R.drawable.mood_24dp_5f6368_fill0_wght400_grad0_opsz24),
                        contentDescription = "emojis",
                        modifier = Modifier
                            .padding(start = 8.dp)
                            .clickable {
                                //TODO DO SOMETHING to show emojis
                            }
                            .size(30.dp)
                    )
                    //Reply text message
                    Box(
                        modifier = Modifier
                            .padding(horizontal = 8.dp)
                            .weight(1f)
                    ) {
                        // Placeholder Text
                        if (state.replyMessage.isEmpty()) {
                            Text(
                                text = "Enter your message here...",
                                style = TextStyle(color = Color.Gray)
                            )
                        }

                        // BasicTextField
                        BasicTextField(
                            value = state.replyMessage,
                            onValueChange = {
                                onActions(MessageScreenAction.onReplyMessageChange(it))
                            },
                            modifier = Modifier.fillMaxWidth()
                        )
                    }
                        Icon(
                            imageVector = ImageVector.vectorResource(id = R.drawable.attachment) ,
                            contentDescription = "attachment",
                            modifier = Modifier
                                .padding(end = 8.dp)
                                .clickable {
                                    //TODO DO SOMETHING about sharing attachments
                                    onActions(MessageScreenAction.onShowAttachmentDropDownMenu)

                                }
                                .size(30.dp)
                        )






                    Icon(
                        imageVector = ImageVector.vectorResource(id = R.drawable.baseline_camera_alt_24),
                        contentDescription = "camera",
                        modifier = Modifier
                            .padding(end = 8.dp)
                            .clickable {
                                //TODO DO SOMETHING about camera feature
                            }
                            .size(30.dp)
                    )
                    
                }
                Spacer(modifier = Modifier.width(8.dp))
                Box(modifier = Modifier
                    .size(50.dp)
                    .clip(CircleShape)
                    .background(Color.Green)
                    .clickable {
                        //TODO implement the audio recording button when there is no message typed
                    },
                    contentAlignment = Alignment.Center

                    ){
                    Icon(
                        imageVector = if (state.replyMessage == "") ImageVector.vectorResource(id = R.drawable.baseline_mic_24) else ImageVector.vectorResource(
                            id = R.drawable.send_24dp_5f6368_fill0_wght400_grad0_opsz24
                        ),
                        contentDescription = if (state.replyMessage == "") "Mic" else "Send",
                        modifier = Modifier
                            .size(40.dp)
                    )
                }
            }
            // Attachments Dropdown Menu
            if (state.showAttachmentDropDown) {
                AttachmentsDropDownMenu(
                    state = state,
                    action = onActions,
                    modifier = Modifier
                        .padding(8.dp) // Positioning near the attachment button
                )
            }

        }
    }


}

Solution

  • Replace the manual offset logic with a combination and padding to achieve the "drop-up" behavior.

    Update Code As per below:

      @Composable
    fun AttachmentDropDownMenu (
    modifier: Modifier = Modifier,
        state: MessageScreenState,
        action: (MessageScreenAction) -> Unit
    ){
    Box(modifier = modifier) {
            DropdownMenu(
                expanded = state.showAttachmentDropDown,
                onDismissRequest = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
                modifier = Modifier
                    .background(MaterialTheme.colorScheme.surface) // Optional background styling
            ) {
                DropdownMenuItem(
                    onClick = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
                    text = { Text(text = "Photo") }
                )
                DropdownMenuItem(
                    onClick = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
                    text = { Text(text = "Video") }
                )
                DropdownMenuItem(
                    onClick = { action(MessageScreenAction.onHideAttachmentDropDownMenu) },
                    text = { Text(text = "Document") }
                )
            }
        }
    }
    

    Place the AttachmentsDropDownMenu above the button.

    @Composable
    fun MessagesScreen(
        modifier: Modifier = Modifier,
        id: Int,
        state: MessageScreenState,
        onActions: (MessageScreenAction) -> Unit
    ) {
        Scaffold(
            modifier = modifier.fillMaxSize()
        ) { innerPadding ->
            Column(
                modifier = Modifier.padding(innerPadding)
            ) {
                LazyColumn(
                    modifier = Modifier
                        .fillMaxSize()
                        .weight(1f)
                ) {
                    items((1..100).toList()) {
                        Text(text = "item ${it}")
                    }
                }
    
                // Reply Row
                Box(modifier = Modifier.fillMaxWidth()) {
                    Row(
                        modifier = Modifier
                            .align(Alignment.BottomCenter)
                            .padding(8.dp)
                            .height(50.dp)
                            .fillMaxWidth()
                            .clip(RoundedCornerShape(32.dp))
                            .background(Color.LightGray),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        // Existing Icons and TextField
                        Icon(
                            imageVector = ImageVector.vectorResource(id = R.drawable.attachment),
                            contentDescription = "attachment",
                            modifier = Modifier
                                .clickable {
                                    onActions(MessageScreenAction.onShowAttachmentDropDownMenu)
                                }
                                .padding(8.dp)
                        )
                        // Other icons here...
                    }
    
                    // Attachments Dropdown Menu
                    if (state.showAttachmentDropDown) {
                        AttachmentsDropDownMenu(
                            state = state,
                            action = onActions,
                            modifier = Modifier
                                .align(Alignment.TopCenter) // Align dropdown above the button
                                .padding(bottom = 50.dp) // Adjust as per button height
                        )
                    }
                }
            }
        }
    }