Table of content
ViewPager in Compose in Android
To create the view pager in android using jetpack compose we need to follow the below steps. Lets starts coding together and enjoy learning. ViewPage2
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 :
- Colors 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
Thanks for checking this. Happy coding !