<@U6Q90DDHR> i have a pagerscreen with 4 pages, 3 ...
# compose-wear
f
@yschimke i have a pagerscreen with 4 pages, 3 of those have a scaling lazy column. I manually implemented 3 differents column state to maintain the scroll state, but i have a focus problem. In particular, when i switch page with an horizontal swipe, the elements in the page are tappable only after a vertical scroll. Do you know a way to request the focus after the page selection? I will provide you a repro, if needed, thanks :)
y
I think a sample would be helpful, I didn't quite follow this
In particular, when i switch page with an horizontal swipe, the elements in the page are tappable only after a vertical scroll.
Horologist has a ScratchActivity, you can remove the guts of and put as a sample on a PR, so it's easier to share a working repro without just being a standalone code snippet.
RSB scrolling will need to follow the active screen, but sounds like you are talking about finger scrolling, which I'd expect to always go to the component your finger is on.
Copy code
HorizontalPager(
            modifier = modifier,
            state = state,
            flingBehavior = HorizontalPagerDefaults.flingParams(state),
        ) { page ->
            ClippedBox(state) {
                HierarchicalFocusCoordinator(requiresFocus = { page == state.currentPage }) {
                    content(page)
                }
            }
        }
HierarchicalFocusCoordinator manages which one is active
And else where if you use
rememberActiveFocusRequester
then RSB focus will be right.
f
Yeah, i saw the implementation of PagerScreen yesterday, but it seems that the focus is requested only after an interaction with the new active page. Later today i will try to create a repro as you said but, meanwhile, i can share a video of the problem (the copies are in italian, but the problem isn't in the copies :D) and a snippet:
Copy code
WearNavScaffold(
    modifier = Modifier.background(Color.Black),
    startDestination = startDestination,
    navController = navController,
    state = navHostState
) {

    composable(route = Section.Navigation.baseRoute) {

        val modifier = if(currentPage == 0) {
            Modifier.edgeSwipeToDismiss(swipeToDismissBoxState)
        } else {
            Modifier.unswipeable()
        }

        PagerScreen(
            modifier = modifier,
            state = pagerState
        ) { selectedPage ->
            currentPage = pagerState.currentPage

            when (selectedPage) {
                0 -> {
                    PageScaffold(
                        columnState = linesListColumnState,
                        content = { columnState ->
                            LinesView(
                                viewModel = hiltViewModel(),
                                navController = navController,
                                columnState = columnState
                            )
                        }
                    )
                }

                1 -> {
                    PageScaffold(
                        columnState = favLinesColumnState,
                        content = { columnState ->
                            FavoritesLinesView(
                                context = mainActivity,
                                viewModel = hiltViewModel(),
                                navController = navController,
                                columnState = columnState
                            )
                        }
                    )
                }
                2 -> {
                    PageScaffold(
                        columnState = mapColumnState,
                        content = { columnState ->
                            MapView(
                                navController = navController,
                                columnState = columnState
                            )
                        }
                    )
                }

                3 ->
                    PageScaffold(
                        columnState = infoColumnState,
                        content = { columnState ->
                            InfoView(
                                columnState = columnState,
                                onUpdateDataTapped = onUpdateDataTapped,
                                onEmailFeedbackTapped = {
                                    openEmail(mainActivity)
                                }
                            )
                        }
                    )
            }
        }
    }
Copy code
@OptIn(ExperimentalHorologistApi::class)
@Composable
private fun PageScaffold(
    columnState: ScalingLazyColumnState,
    content: @Composable (ScalingLazyColumnState) -> Unit
) {
    Scaffold(
        timeText = { CustomTimeText() },
        positionIndicator = {
            PositionIndicator(columnState.state)
        }) {
        content(columnState)
    }
}
a
Hi. I was recently solving similar issue when navigating between two screens. Maybe this will help you https://stackoverflow.com/a/77122537/19289823
👀 1
😓 1
y
There is
rememberActiveFocusRequestor
that should handle that with one line
plus green 1
f
@yschimke i'm trying to push a new branch on Horologist repo with my repro, to do a PR...but i'm getting 403
y
Fork the repository, and push your branch there.
👍 1
Yep, I can reproduce. I see what you mean.
I think the HorizontalPager doesn't know it should finish scrolling, and the first click seems to let ScalingLazyColumn take over scrolling.
f
oh ok, you have created a repro faster than me ahahah
y
cc @stevebower In case you have a suggestion.
f
yes, after the first scroll, the tap seems working fine
do you want a github issue?
y
No I meant Wear Compose.
Do you think it's an issue in Horologist?
f
uhm...maybe it could be a focus problem...i dunno
I opened a ticket due to thread inactivity --> https://issuetracker.google.com/issues/303807950
Hi @yschimke, what do you think about the answer? https://issuetracker.google.com/issues/303807950
y
Probably worth checking that, it should be simple to add that to your repro, and then ask @stevebower to take another look.
But in other ways I'm more amazed that vertically scrolling pages (ScalingLazyColumn) work this well inside horizontal pagers.
f
i asked him more info about his idea because i think i don't get the role of another focus coordinator (and about the focus codes in general, sorry XD) --> https://issuetracker.google.com/issues/303807950#comment3
y
It's somewhat new territory for Wear. Mobile doesn't use focus like this much. I'll discuss tomorrow
🔝 1
So, it seems to relate to the PagerState still being scrolling, and HorizontalPager intercepting scroll events.
Copy code
TimeText(endCurvedContent = {
                curvedText(
                    "Pager: ${
                        pagerState.isScrollInProgress
                    }"
                )
            })
This makes it predictable, once it says false you can scroll the SLC.
Both time or an extra click fix scroll state. But I don't really understand if it's wrong.
I suspect if you really want it fixed, then debugging the interactions with Pager scroll events would help get it fixed sooner. But otherwise I'm not sure it's going to be fixed until their is a strong pattern that requires it.
👍 1