--
Implementing onBoarding ViewPager Using JetPack Compose
Lets jump straight in to the example
Necessary implementation to the app level build gradle file
// Paging Compose
implementation "com.google.accompanist:accompanist-pager:0.13.0"
implementation "com.google.accompanist:accompanist-pager-indicators:0.13.0"
implementation "androidx.hilt:hilt-navigation-fragment:1.0.0"
implementation "androidx.hilt:hilt-navigation-compose:1.0.0-alpha03"
implementation "androidx.navigation:navigation-compose:2.4.0-alpha04"
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
First we will be creating a data class which holds a data for on boarding screen
data class SampleOnBoard(
val image: Int,
val title: String,
val desc: String
)
So i am passing value to data class SampleOnBoard
val onBoardItem = listOf(
SampleOnBoard(
R.drawable.onboard1,
"Make it Easy One",
"Lorem Ipsum is simply dummy text of the printing and typesetting Industry."
),
SampleOnBoard(
R.drawable.onboard2,
"Make it Easy Two",
"Lorem Ipsum is simply dummy text of the printing and typesetting Industry."
),
SampleOnBoard(
R.drawable.onboard3,
"Make it Easy Three",
"Lorem Ipsum is simply dummy text of the printing and typesetting Industry."
)
)
So final Page of SampleOnBoard class will be
data class SampleOnBoard(
val image: Int,
val title: String,
val desc: String
)
val onBoardItem = listOf(
SampleOnBoard(
R.drawable.onboard1,
"Make it Easy One",
"Lorem Ipsum is simply dummy text of the printing and typesetting Industry."
),
SampleOnBoard(
R.drawable.onboard2,
"Make it Easy Two",
"Lorem Ipsum is simply dummy text of the printing and typesetting Industry."
),
SampleOnBoard(
R.drawable.onboard3,
"Make it Easy Three",
"Lorem Ipsum is simply dummy text of the printing and typesetting Industry."
)
)
Next we will be creating a viewmodel class called OnBoardViewModel
class OnBoardViewModel : ViewModel() {
private val _currentPage = MutableStateFlow(0)
val currentPage: StateFlow<Int> get() = _currentPage
fun setCurrentPage(currentPage: Int) {
_currentPage.value = currentPage
}
}
we created a StateFlow for current page. The main use of StateFlow is its an interface which has read only property it always return the updated value which is implemented through MutableStateFlow if same value updated means it doesn't return the value.
Lets have a look in to MainActivity code, the use of line is marked with double slash on the program
@ExperimentalPagerApi
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.statusBarColor = ContextCompat.getColor(this, R.color.gray)
setContent {
OnBoardScreenTheme {
Surface(color = MaterialTheme.colors.background) {
OnBoardScreen()
}
}
}
}
}
@ExperimentalPagerApi
@Composable
fun OnBoardScreen() {
val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
val onBoardViewModel : OnBoardViewModel = viewModel()
val context = LocalContext.current
val currentPage = onBoardViewModel.currentPage.collectAsState()
Toast.makeText(context, "${currentPage.value}", Toast.LENGTH_SHORT).show()
val pagerState = rememberPagerState(
pageCount = onBoardItem.size,
initialOffscreenLimit = 2,
initialPage = 0,
infiniteLoop = false
)//Scafffold - helps us to design UI by using Material Layout Design Structure it allocate slot for common top level material component like topappbar,Bottomappbar,Drawer and Floating action button.// Scaffold(
modifier = Modifier.fillMaxSize(),
scaffoldState = scaffoldState
) { //Just make use of all material component
Surface(
modifier = Modifier.fillMaxSize()
) {
scope.launch { //Moves the page to next view based on postion
pagerState.animateScrollToPage(
page = currentPage.value
)
}//Similar to FrameLayout in android we can overlap view inside Box Box(
modifier = Modifier
.fillMaxWidth()
.background(Gray200)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
HorizontalPager(
state = pagerState
) { page ->
Column(
modifier = Modifier
.padding(top = 65.dp)
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = onBoardItem[page].image),
contentDescription = "OnBoardImage",
modifier = Modifier
.size(250.dp)
)
Text(
text = onBoardItem[page].title,
modifier = Modifier
.padding(top = 50.dp),
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 20.sp
)
Text(
text = onBoardItem[page].desc,
modifier = Modifier
.padding(30.dp),
color = Color.White,
fontSize = 18.sp,
textAlign = TextAlign.Center
)
}
}
}
Box(
modifier = Modifier
.align(Alignment.BottomCenter)
) {
Row(
modifier = Modifier
.padding(bottom = 20.dp)
.fillMaxWidth(),
horizontalArrangement = if (pagerState.currentPage != 2 ) {
Arrangement.SpaceBetween
} else {
Arrangement.Center
}
) {
if (pagerState.currentPage == 2) {
OutlinedButton(
onClick = {
Toast.makeText(context, "Start the Screen", Toast.LENGTH_SHORT).show()
},
shape = RoundedCornerShape(45.dp)
) {
Text(
text = "Get Started",
modifier = Modifier.padding(
vertical = 8.dp,
horizontal = 40.dp
),
color = Color.Black
)
}
} else {
Text(
text = "Skip",
color = Color.White,
modifier = Modifier.padding(start = 20.dp),
fontSize = 18.sp,
fontWeight = FontWeight.Medium
)
Text(
text = "Next",
color = Color.White,
modifier = Modifier
.clickable {
onBoardViewModel.setCurrentPage(pagerState.currentPage + 1)
}
.padding(end = 20.dp),
fontSize = 18.sp,
fontWeight = FontWeight.Medium
)
}
}
}
}
}
}
}