adjpd

    adjpd

    1 year ago
    Dialog
    and
    DropDownMenu
    unexpand and hide, respectively, when the user touches outside the composables. How can I implement this myself? I want to hide a composable if the user touches outside the composable.
    The only idea I have is to make a custom class that extends
    AbstractComposeView
    so I can get access to
    onTouchEvent
    and check if the click is within the composable. Is there an easier way? It feels rather heavyweight to use an
    AbstractComposeView
    rather than the usual compose coding style for something fairly simple.
    Alexandre Elias [G]

    Alexandre Elias [G]

    1 year ago
    you can use a
    Modifier.pointerInput
    for this. I suggest imitating the Scrim pattern in the built-in ModalDrawer: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]otlin/androidx/compose/material/Drawer.kt;l=374?q=ModalDrawer
    adjpd

    adjpd

    1 year ago
    So.... display a box that fills the screen and put a click listener on that? Or is there more to it that that?
    Alexandre Elias [G]

    Alexandre Elias [G]

    1 year ago
    Basically that's all it is. But make sure to use a
    Modifier.pointerInput
    listener instead of a
    Modifier.clickable
    because the latter is designed for things like buttons, and will have undesirable effects on screen reader accessibility
    adjpd

    adjpd

    1 year ago
    My problem is that my component doesn't take up all the screen, the the scrim doesn't take up all the screen. I could move the scrim further up the composable hierarchy so it does take up all the space. But then my problem is that other click listeners further down the hierarchy will be called before the one on the scrim.
    Alexandre Elias [G]

    Alexandre Elias [G]

    1 year ago
    Right.
    ModalDrawer
    is written in a such a way to take priority over the children (scrim as peer to content lambda instead of parent), I recommend imitating it.
    adjpd

    adjpd

    1 year ago
    Unless I'm mistaken, ModalDrawer's scrim can intercept the events because it's composed after the other composables, but not interecept the events in the drawer, since it's composed before that. My component, unlike
    ModalDrawer
    , isn't on the root level with the other composables. So I'm unsure if this will work.
    Unless this is the thing I'm misunderstanding. Semantics are still a mystery.
    .semantics(mergeDescendants = true) {
                    contentDescription = closeDrawer
                    onClick { onClose(); true }
                }
    Alexandre Elias [G]

    Alexandre Elias [G]

    1 year ago
    Indeed, the way I would recommend to solve this is to refactor your code to get something on the root level. (Semantics are there to support screen readers but they don't affect ordinary touch input at all)
    adjpd

    adjpd

    1 year ago
    Thanks, that's the conclusion I'm arriving at. I'm slightly worried the
    scrims
    clicks my fall through the other composables but since that isn't the case, I assume, with
    ModalDrawer
    I guess it will work. Thanks Alexandre for your time. Hopefully I'll have a decent solution soon.
    Actually,
    DropDownMenu
    manages to do this with a
    AbstractComposeView
    (here precisely) but getting
    AbstractComposeView
    to work within a
    Compose
    project, rather than from the Android view system, is a new adventure...