admin管理员组

文章数量:1129091

My current android project has and xml list and list items, with each list item having a contect menu.

the context menu is implemented using Android Compose DropDownMenu as follows:

the list item xml contains this view

    <androidxpose.ui.platform.ComposeView
        android:id="@+id/cvCustomButtonDdm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_gravity="end|top" />

and within my BaseExpandableListAdapter (getChildView) function i "build" each list item as follows:-

    val showDropDownMenuState = MutableStateFlow(false)

    ui.ivCustomButton.setOnClickListener {
        showDropDownMenuState.value = true
        onCustomButtonClick(customButton, showDropDownMenuState)
    }

and

private fun onContextMenuClick(showDropDownMenuState: MutableStateFlow<Boolean>) {
    ui.cvCustomButtonDdm.apply {

        setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
        setContent {
            val showDropDownMenu by showDropDownMenuState.collectAsStateWithLifecycle()

            SideEffect {
                println("showDropDownMenu = $showDropDownMenu")
            }

            ItemSettingsDdm(
                showDropDownMenu = showDropDownMenu,
                myDataItem = myDataItem!!,
                onAllocated = { myDataItem?.let { onAllocatedCallback?.invoke(it) } },
                onCompleted = {
                    myDataItem?.let {
                        onProgressCompletedClickCallback?.onProgressCompleted(
                            it
                        )
                    }
                },
                onDeleted = {
                    if (!isReadOnly) {
                        val dialog = FDeleteItemUniversal<>()
                            .withTitle(context.getString(R.string.delete_myDataItem_label))
                            .withMessage(context.getString(R.string.delete_myDataItem))
                        dialog.setItemToDelete(myDataItem)
                        onDeletedCallback?.let { dialog.setCallback(it) }
                        dialog.show(context.toAppActivity()?.supportFragmentManager)
                    } else {
                        context.err(R.string.myDataItem_is_readonly)
                    }
                },
                onDismissRequest = {
                    showDropDownMenuState.value = false
                }
            )
        }
    }
}

when i test the context menu by clicking on it to show on each individual list item, initially the SideEffect debug messages make sense as the menu is shown then dismissed as shown here:-

 showDropDownMenu = true
 showDropDownMenu = false

 showDropDownMenu = true
 showDropDownMenu = false

 showDropDownMenu = true
 showDropDownMenu = false

 showDropDownMenu = true
 showDropDownMenu = false

 showDropDownMenu = false
 showDropDownMenu = true

then as the last pair of logs shows the drop down menu state is in the wrong order why is the val showDropDownMenuState = MutableStateFlow(false) getting confused?

what have i done wrong to achieve this "feature" ?

I have implemented a very "Hacky" fix as follows in my onDismiss() function as shown here

 @Suppress("ControlFlowWithEmptyBody")
 if (showDropDownMenuState.value) {
 } else showDropDownMenuState.value = true

 showDropDownMenuState.value = false

the state flow current value becomes "unsynced" with the visible state of the drop down menu, e.g. the drop down menu is visible and the MutableStateFlow value is false.

本文标签: Android Compose Context menu in xml list item does not dismissStack Overflow