What is the typical pattern for AlertDialog when u...
# compose-wear
y
What is the typical pattern for AlertDialog when used with navigation? https://github.com/yschimke/rememberwear/blob/main/wear/src/main/kotlin/com/google/wear/soyted/ui/RememberWearAppScreens.kt#L105-L128
Copy code
composable(
                    Screens.LoginDialog.route
                ) {
                    AlertDialog(
                        title = {
then
Copy code
positiveButton = {
                            Button(onClick = {
                                viewModel.continueLogin()
                                navController.popBackStack()
Is there an argument for the dialog knowing how to close itself? Or is this something that would come with a wear equivalent of
NavGraphBuilder.dialog
from navigation-compose?
FWIW Dialog was amazingly simple to integrate with and look great straight away.
I've also seen examples of the non-wear compose version like
Copy code
if (dialogShown) {
            AlertDialog(
Is that supported something to consider when it's above other content? Or is it different because these are full screen for Wear?
j
@Steve Bower [G] can you comment on this
y
Just noticed the button is skewed because I didn't implement a negative button 😞 Sorry!
Use the
if (dialogShown)
code in the destination that wants to start the AlertDialog
👍🏻 1
s
@yschimke There is another overload of AlertDialog that takes a single slot, intended for a vertical stack of chips - but if positive/negative sentiment buttons don't make sense for your use-case, you could pass a Button there. Also, note that both AlertDialog and ConfirmationDialog work with swipe-to-dismiss by default - so if using them as part of another composable in a nav destination, you need to handle that with a LaunchedEffect to manage whatever state you're using to show/hide the dialog. UPDATE: that would work within a SwipeToDismissBox, but with SwipeDismissableNavHost, the swipe state is currently held internally, so you wouldn't be able to customise the behaviour.
@Ian Lake I've used the Wear Compose AlertDialog as a navigation destination - it's quite natural given the swipe-to-dismiss handling (which in this context takes you back to the previous destination), whereas the Buttons (or other content passed to the slots) can be used to update state and/or navigate to a new destination. Given that these are full-screen UI, what drawbacks would you envisage for that approach?
y
DialogSample was suggestive of navigation
Copy code
negativeButton = { Button(onClick = {
            /* Do something e.g. navController.popBackStack()*/
        }) { Text("No") } },
@Steve Bower [G] so should current wear dialogs work with the
if (dialog)
mode as non-wear does? Would the LaunchedEffect just trigger that state once (or when conditions require shwoing again), and the composeable would be outside, until close. DialogImpl is just a Column, so what makes it appear above content? Use in a Box, as the last item?
s
The Wear Dialogs do work with conditional statements as part of a higher-level composable, if that suits your workflow, in which case you would control the visibility of the Dialog something like this: var showDialog by remember { mutableStateOf(false) } /* ... set showDialog = true somewhere ... */ if (showDialog) { AlertDialog( title = { Text("the title") }, negativeButton = { Button( onClick = { /* do something here */ showDialog = false }, content = { Text("No") } }, positiveButton = { Button( onClick = { /* do something here */ showDialog = false }, content = { Text("Yes") } } }
But, you might need to disable the swipe-to-dismiss if you are using wear.compose.navigation (i.e. SwipeDismissableNavHost) - unless it makes sense for swipe-to-dismiss to trigger a swipe back to the previous level. This would do it: @OptIn(ExperimentalWearMaterialApi::class) public fun Modifier.unswipeable() = this.then( Modifier.draggable( orientation = Orientation.Horizontal, enabled = true, state = DraggableState {} ) )
y
What is the magic that makes it appear unconditionally on top?
As opposed to inline?
s
You beat me to it! Taking a step back - if you make the Dialog a navigation destination, things work more naturally IMO, because the swipe-to-dismiss acts as a default cancellation of the dialog back to the previous navbackstackentry and the buttons or chips can effect whatever action is otherwise necessary and/or perform navigation. Really, given that it's full-screen, the dialog IS a screen for the purposes of navigation. But, you can make it work if you code the visibility of the dialog manually - it's just more effort. Maybe there are cases where it's worth it? Interested to hear what @Ian Lake sees as the downside of treating Wear dialogs as (full screen) navigation destinations.
y
Good point - I hope you argue for keeping it as a nav target, it's full screen for Wear, swipe dismiss is useful, and it means it work unformly without embedding it at top level of the screen in a Box.
i
Okay, I think the point I was missing is that Wear Compose's AlertDialog isn't a 'dialog' at all. It's just a
Column
with predefined slots and a confusing name since it acts nothing like a Compose
Dialog
, doesn't have anything that makes it actually full screen (being just a
Column
, it only looks full screen if you put it as the same content within an already full screen
Box
- put it in a
Column
or put something after it, and it won't appear full screen above anything at all), and doesn't handle back at all (unlike Compose
Dialog
).
😁 1
With that in mind, sure, any destination can have a
Column
in it
Given that Wear already styles Android dialogs as full screen dialogs last I checked, I'm not entirely sure why this embedded within the parent layout Column based approach was chosen. Perhaps Steve can comment on that?
👍🏻 1
s
I'll create a discussion document internally, so that we can compare approaches.
1