zero.one
zero.one

Reputation: 1553

Jetpack compose : Problem while swiping pages in pager compasable

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

Upvotes: 7

Views: 2138

Answers (2)

FASius Fox
FASius Fox

Reputation: 51

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()
    }

  }
}

Upvotes: 5

Roman
Roman

Reputation: 870

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

Upvotes: 2

Related Questions