ViewPager in Android Jetpack Compose

Parita Dey
4 min readNov 10, 2023

--

To create the view pager in android using jetpack compose we need to follow the below steps. Lets starts coding together and enjoy learning.

Step 1:

  • Create the Welcome Fragment
class WelcomeScreenFragment :Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
WelcomeScreen(findNavController())
}
}
}
}
}
  • Now creating the WelcomeScreen for the UI part
@Composable
fun WelcomeScreen(navController: NavController) {
val scrollState = rememberScrollState()
Surface(
modifier = Modifier
.fillMaxWidth()
.background(color = onboarding)
) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(scrollState)
.background(color = onboarding),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
){
Image(painter = painterResource(id = R.drawable.logomark), contentDescription = "image", contentScale = ContentScale.None)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, top = 16.dp, bottom = 0.dp, end = 20.dp),
text = "Welcome to the ultimate freud UI Kit!",
style = MaterialTheme.typography.titleMedium.copy(color = Color.White),
textAlign = TextAlign.Center,
)
Text(
text = "Your mindful mental health AI companion for everyone, anywhere 🍃",
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, top = 16.dp, bottom = 0.dp, end = 20.dp),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleSmall.copy(color = Color.White),
)
Image(painter = painterResource(id = R.drawable.welcome_step_one),
modifier = Modifier.padding(0.dp, 32.dp, 0.dp, 0.dp),
contentDescription = "image", contentScale = ContentScale.None)
Button(onClick = {navController.navigate(R.id.viewOnBoarding)}, shape = RoundedCornerShape(60.dp),
colors= ButtonDefaults.outlinedButtonColors(containerColor = Brown61)
, modifier = Modifier
.fillMaxWidth()
.height(76.dp)
.padding(60.dp, 24.dp, 60.dp, 0.dp)) {
Text(text = "Get started ", color=Color.White)
Icon(imageVector = Icons.Default.ArrowForward, contentDescription = "sign in", tint= Color.White)
}
Button(onClick = {navController.navigate(R.id.viewSignUp)},
colors= ButtonDefaults.outlinedButtonColors(containerColor = Color.Transparent)
, modifier = Modifier
.fillMaxWidth()
.padding(14.dp, 12.dp, 14.dp, 0.dp)) {
Text(
text = "Already have an account?",
style = MaterialTheme.typography.bodySmall.copy(color = Color.White),
textAlign = TextAlign.Center
)
Text(text = "Sign In ", style = MaterialTheme.typography.bodyMedium.copy(color = Brown61),
textAlign = TextAlign.Center)
}
}
}
}

So it will look like below

Step 2 :

  • We will create the data class to populate the screen.
data class OnboardingPage(
val background: Color,
val title: String,
val stepNumber: Int,
@DrawableRes val image: Int
)
  • Mock some data
val onboardPages = listOf(
OnboardingPage(
background = step1Green,
title = "Personalize Your Mental Health State With AI",
stepNumber = 1,
image = R.drawable.welcome_step_two
),
OnboardingPage(
background = step2Brown,
title = "Intelligent Mood Tracking & Emotion Insights",
stepNumber = 2,
image = R.drawable.welcome_step_three
),
OnboardingPage(
background = step3Yellow,
title = "Mindful Resources That Makes You Happy",
stepNumber = 3,
image = R.drawable.welcome_step_four
),
OnboardingPage(
background = step4Blue,
title = "Loving & Supportive Community",
stepNumber = 4,
image = R.drawable.welcome_step_five
)
)

Step 3 :

  • Creating the view pager. So creating a new fragment called Onboarding Fragment
class OnboardingFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
OnboardingUI(findNavController(),OnSkipClicked = { findNavController().navigate(R.id.viewOnboardingToLogin) })
}
}
}
}
}
  • Now moving towards creating OnboardingUI()
@OptIn(ExperimentalPagerApi::class)
@Composable
fun OnboardingUI(navController: NavController,OnSkipClicked: () -> Unit) {
val pagerState = rememberPagerState(pageCount = 4)
Column(
modifier = Modifier
.fillMaxWidth()
.background(color = Brown61),
) {
Text(text = "Skip ",
style = MaterialTheme.typography.bodyLarge.copy(color = Color.White),
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth().height(50.dp)
.padding(start=270.dp, top=24.dp)
.clickable { OnSkipClicked() })

HorizontalPager(
state = pagerState, modifier = Modifier
.fillMaxWidth()
.weight(1f)
) { page ->
OnboardingScreen(page = onboardPages[page])
}

HorizontalPagerIndicator(
pagerState = pagerState, modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(16.dp),
activeColor = Color.White
)

AnimatedVisibility(visible = pagerState.currentPage == 3) {
OutlinedButton(
shape = RoundedCornerShape(20.dp),
modifier = Modifier
.fillMaxWidth().height(60.dp)
.padding(start = 24.dp, top=14.dp, end=24.dp, bottom=8.dp),
onClick = {navController.navigate(R.id.viewOnboardingToLogin)},
colors = ButtonDefaults.outlinedButtonColors(
containerColor = colorResource(
id = R.color.BROWN_100
), colorResource(id = R.color.BROWN_100)
)
) {
Text(text = "Let's Start",
style = MaterialTheme.typography.bodySmall.copy(color = Color.White),
textAlign = TextAlign.Center)
}
}
}
}
  • Now we create OnboardingScreen
@Composable
fun OnboardingScreen (page: OnboardingPage){
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(scrollState)
.background(color = Brown61),
horizontalAlignment = Alignment.CenterHorizontally,
){
Image(painter = painterResource(id = page.image) , contentDescription = "Step Number")
Spacer(modifier = Modifier.height(20.dp))
Box(
modifier = Modifier.width(70.dp).height(18.dp)
.clip(CircleShape)
.background(color = page.background),
) {
Text(
modifier = Modifier
.fillMaxWidth(),
text ="Step "+ page.stepNumber.toString(),
style = MaterialTheme.typography.bodySmall.copy(color = Color.White),
textAlign = TextAlign.Center
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
modifier = Modifier
.fillMaxWidth(),
text = page.title,
style = MaterialTheme.typography.bodyLarge.copy(color = Color.White),
textAlign = TextAlign.Center
)
if(page.stepNumber!=4) {
Button(
onClick = {},
shape = RoundedCornerShape(40.dp),
colors = ButtonDefaults.outlinedButtonColors(containerColor = page.background),
modifier = Modifier
.width(64.dp)
.height(64.dp).padding(start=0.dp, top=24.dp, end=0.dp, bottom = 0.dp)
) {
Icon(
imageVector = Icons.Default.ArrowForward,
contentDescription = "sign in",
tint = Color.White
)
}
}
}
}

Step 4 :

  • Colours we used
val onboarding = Color(0xFF121619)
val step1Green = Color(0xFF5A6B38)
val step2Brown = Color(0xFF702901)
val step3Yellow = Color(0xFFA37A00)
val step4Blue = Color(0xFF2F1093)

val White100 = Color(0xFFFFFFFF)
val Brown100 = Color(0xFF1F160F)
val Brown60 = Color(0xFF5C4033)
val Brown50 = Color(0xFFD27D2D)

val Green70 = Color(0xFF3D4A26)
val Brown30 = Color(0xFFFE814B)
val Brown40 = Color(0xFFFE814B)
val Brown61 = Color(0xFF926247)
val Green80 = Color(0xFF3D4A26)
  • So at the end it will look like this

Github link : https://github.com/paritadey/MentalHealthApp/tree/loginFlow

Thanks for checking this. Happy coding !

--

--