Jetpack compose : Problem while swiping pages in pager compasable
Asked Answered
N

2

7

I'm building a registration page with jetpack compose and I have implemented it in a horizontal pager linked with TabRow to display signup and login page respectively

but when I swipe to the other page (login or signup), the next page will build only after the swipe offset exceeds apporximately 50% of the screen width, and the pervious page will be rendered in the other page as shown in the video below

  @OptIn(ExperimentalPagerApi::class)
  @Composable
  fun RegistrationHorizontalPageView() {
  val tabRowState = viewModel<TabRowViewModel>()


     HorizontalPager(
     count = 2,
     state = tabRowState.pagerState,
     modifier = Modifier.fillMaxSize(),
     verticalAlignment = Alignment.Top
 ) {


    if(currentPage == 0){
        RegistrationPage()
    }else{
        LoginPage()
    }

  }
}

how to fix this ?demo for the problem

Nosepiece answered 1/12, 2022 at 10:54 Comment(2)
I have a similar problem. Have you solved it?Spikelet
it was just a bug with the library itself, after it was updated, the problem gone, so if you are using the most recent version of library then you should have no problem like thisNosepiece
P
5

Replace currentPage by page

@OptIn(ExperimentalPagerApi::class)
@Composable
fun RegistrationHorizontalPageView() {
  val tabRowState = viewModel<TabRowViewModel>()


  HorizontalPager(
     count = 2,
     state = tabRowState.pagerState,
     modifier = Modifier.fillMaxSize(),
     verticalAlignment = Alignment.Top
 ) { page -> 


    if(page == 0){
        RegistrationPage()
    } else {
        LoginPage()
    }

  }
}
Porscheporsena answered 21/8, 2023 at 13:35 Comment(2)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Yumuk
This is the correct solution. Use the page parameter that's provided in the trailing lambda rather than using the pagerState.Mathamathe
U
2

I suggest to use a list of tab Items that contain different elements of view. Make sure to not use if else statements based on the page state because it is changing only after 50%, rather try to create your view always available.

For example you can do something like this:

sealed class TabItem(var title: String, var color: Color, content: @Composable () -> Unit) {
    object Registration : TabItem("REGISTRATION", Color.Red, { /* you can add here your composable*/} )
    object Login : TabItem("LOGIN", Color.Blue, { /* you can add here your composable*/} )
}

Usage:


@OptIn(ExperimentalPagerApi::class)
@Composable
fun MyScreen() {
    val pagerState = rememberPagerState()
    val tabs = listOf(TabItem.Registration, TabItem.Login)

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Top
    ) {
        TabRow(
            selectedTabIndex = pagerState.currentPage,
            indicator = { positions ->
                TabRowDefaults.Indicator(
                    Modifier.pagerTabIndicatorOffset(pagerState, positions)
                )
            }
        ) {
            tabs.forEachIndexed { index, tab ->
                val isSelected = pagerState.currentPage == index
                Tab(
                    selected = isSelected,
                    text = {
                        Text(text = tab.title)
                    },
                    onClick = {}
                )
            }
        }
        HorizontalPager(
            count = tabs.size, 
            state = pagerState
        ) { page ->
            Box(modifier = Modifier
                .fillMaxSize()
                .background(tabs[page].color) // for the example, showing that both pages are rendered
            ){
                Text( modifier = Modifier.fillMaxWidth(), text = tabs[page].title)
            }
        }
    }
}

Result:

enter image description here

Uniat answered 4/12, 2022 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.