Hello! The NavView of my app is composed by: Mat...
# compose-wear
f
Hello! The NavView of my app is composed by: MaterialTheme>SwipeToDismissBox>WearNavScaffold>PagerView(inside a scrollable block). I was wondering if having a PagerView inside a scrollable could be ok because, after scrolling horizontaly in a page with button, i need two tap to interact with that button (the first tap isn't recognized or is fired by something else i suppose). Every page inside the PagerView has a ScalingLazyColumn with the column state of the scrollable block. Thanks for your help (i hope so :D) ps: if you need more info about my app ui structure, feel free to ask
y
Why do you need SwipeToDismissBox and WearNavScaffold also?
I'm not sure about the double tap, but should work, so next is probably a bug with executable repro.
f
Does WearNavScaffold handle back swipe too? Btw i think that SwipeToDismissBox is an old refuse in my code, because it doesn't work with PagerScreen ahahaah (and that's correct)
Yeah, the double tap could be a bug, because it has to work with the first one only (or maybe it's the complex layout in my app that is the cause). If you needed, i can provide you a sample project and a video to show the bug.
y
You can pass the swipe to dismiss state into WearNavScaffold. I'll send a sample later.
f
Cool, thanks! I still trying to figure out the double tap button, so weird :'D
y
This sample shows combining them
Copy code
val swipeToDismissBoxState = rememberSwipeToDismissBoxState()
    val navHostState =
        rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState)
    val navController = rememberSwipeDismissableNavController()
Then passed into the screen with a pager
Copy code
@Composable
fun SamplePagerScreen(swipeToDismissBoxState: SwipeToDismissBoxState) {
    PagerScreen(
        modifier = Modifier.edgeSwipeToDismiss(swipeToDismissBoxState),
        state = rememberPagerState {
            10
        }
    ) {
        PagerItemScreen(item = "item $it")
    }
}
f
Thanks man, very kind! I'll try it asap...maybe it will fix double tap bug too. Do you still need the sample to reproduce this bug? I'm not at pc right now, but this afternoon yep
y
If still failing, yep code as text to repro would be helpful. I'll take a look on Tuesday (Monday is a holiday)
f
Sure...See you on Tuesday! Have a nice weekend ;)
Hi @yschimke! I have attached a zip with the sample project. I can reproduce the double tap bug. Moreover, i'm definitely makeing a mistake in my code because i can't scroll pages after changing page in PagerScreen (with horizontal swipe). Can you please help me to figure out what's wrong? I think that the "scrollable" func is in the wrong place, but i'm too newbie to be sure of that :P. These two bugs are the only remaining in my app (atm :D) and i don't how to fix them XD
OT: i realized that i don't need swipeToDismissHandler in my app
y
OK, couple of issues, one easy one for you, one harder one for us.
1. We should document it better, but 0.4.x is tracking the betas of Compose 1.5 and Wear Compose 1.2. So you should make sure you use those versions or downgrade to Horologist 0.3.x
2. There isn't currently a navigation DSL method, similar to scrollable() for the pager screen. See https://github.com/google/horologist/issues/823
So this, is sharing column state, that isn't safe/working.
Copy code
scrollable(route = "BaseNav") { scrollableScaffoldContext ->
                PagerScreen(
                    state = pagerState
                ) { selectedPage ->

                    when(selectedPage) {
                        0 -> PageOne(
                            navController = navController,
                            columnState = scrollableScaffoldContext.columnState
                        )

                        1 -> PageTwo(
                            navController = navController,
                            columnState = scrollableScaffoldContext.columnState
                        )
Instead of
scrollable
you'll need to use
composable
and then create the ColumnState yourself. That also means for now putting the PositionIndicator and TimeText on each page.
f
thanks for the answer, i'll try to fix with your suggestions 🙂
y
I should really implement that issue, would be nice, just not sure of the right API for it.
f
Hi! I have replace scrollable to composable as you said, and i created N column state with "ScalingLazyColumnDefaults.belowTimeText().create()". Then i disabled time text and position indicator, and i implemented them in every page (i need only timetext atm):
Copy code
@Composable
private fun PagerContent(
    focusRequester: FocusRequester,
    content: @Composable () -> Unit
) {
    Scaffold(
        modifier = Modifier
            .focusRequester(focusRequester)
            .focusable(),
        timeText = {
            TimeText()
        },
        content = {
            content()
        }
    )
}
The problem is that, when i click a button in a page inside PagerScreen to navigate in a nested page and then i go back, i land in the first page. I also tried changing the initial page of a remembered pager state, without changes. update: this problem is due to the rollback of Horologist to 0.3.11, fixed in 0.4.8 Another question i have is the following. I'm trying to implement swipeToDismissBoxState as you suggested me few days ago. The problem is that, differently from SwipeToDismissBox, i don't have a closure to customize what happen when i swipe back, but only when the swipe back is enabled. Am i missing something? Thanks for your time! :)
y
do you have a sample you can share? There are two things that have swipeable behaviour here. • SwipeDimissableNavHost (which wraps a SwipeToDismissBox) • HorizontalPager You create the NavHost first, but then you want the pager screen to receive events, so coordinating via the swipeToDismissBoxState allows you to have the pager (or some full screen map) working.
What do you want to do on the swipe lambda?
f
Sorry for the late answer, i was very busy and i coudn't work on my project in my spare time 🙂! I don't have a sample unfortunately, but i can create it, if you need it. The problem is that, when i swipe to close my WearNavScaffold (which state is rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState) ) with an inner PagerScreen (with edgeSwipeToDismiss set), a black page appears, and a warning said:
SwipeDismissableNavHost: Current backstack entry is empty. Please ensure:
1. The current WearNavigator navigation backstack is not empty (e.g. by using androidx.wear.compose.navigation.composable to build your nav graph).
2. The last entry is not popped prior to navigation (instead, use navigate with popUpTo).
3. If the activity uses FLAG_ACTIVITY_NEW_TASK you should also set FLAG_ACTIVITY_CLEAR_TASK to maintain the backstack consistency.
And that's weird, because the parent of WearNavScaffold is only a MaterialTheme :/