Navigation with Jetpack Compose (Jetpack compose with mvvm part B)
In part A of Jetpack Compose with mvvm,we covered fetching data from moviedb and showing it as a list using composable function.If you missed that article,you can find it from below
Now next task is to add a click event to the list, and clicking on an item showing the details page.
For that first we need to have a details page ui ready.Our details page will looks like below.
Lets get Started
So create a seperate package for details under ui package,and create one MovieDetails.kt file.
Create the composable function for details text,which will contain two text inside a Column.
@Composable
fun MovieDetailsText(movieItem: MovieItem){
Column(modifier = Modifier.padding(10.dp)) {
movieItem.title?.let {
Text(text = it, fontFamily = FontFamily.Serif,
fontWeight = FontWeight.Normal,
fontSize = 24.sp)
}
Text(text = movieItem.overview,Modifier.padding(top=10.dp),fontFamily = FontFamily.Serif,
fontWeight = FontWeight.Normal,
fontSize = 16.sp)
}
}
Next is to have a Banner image composable function.
Which will looks like below
@Composable
fun MovieDetailsBanner(movieItem: MovieItem){
Row(modifier = Modifier
.fillMaxWidth()
.height(300.dp)) {
Image(modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),painter = rememberCoilPainter(request = Constants.BASE_IMAGE_URL+movieItem.backdrop_path) , contentDescription = "")
}
}
Now we have composable function for banner and details text ,next is to write a composable function to put these two functions.Which can have a Column to align vertically
@Composable
fun MovieDetails(movieItem: MovieItem){
Column() {
MovieDetailsBanner(movieItem = movieItem)
MovieDetailsText(movieItem = movieItem)
}
}
Navigation Component
Details Ui is ready, now to communicate with list and details page and pass data between these two page.For that we can use navigation component.
Add navigation compose library to build.gradle
implementation 'androidx.navigation:navigation-compose:2.4.0-alpha03'
Add NavController and onItemClicked(which is defined inside viewmodel,check partA for code)to MainList composable function.
NavController
is the central API for the Navigation component. It is stateful and keeps track of the back stack of composables that make up the screens in your app and the state of each screen
@Composable
fun MainList(navController: NavController,
mainViewModel: MainViewModel){
MovieList(navController = navController,movieList = mainViewModel.trendingMovies,
onItemClicked = mainViewModel::itemClicked)
}
pass both to the child item for which click is required
@Composable
fun ListViewItem(
navController: NavController,
movieItem: MovieItem,
onItemClicked: (item: MovieItem) -> Unit
) {
ListViewItem(movieItem = movieItem, modifier = Modifier
.padding(8.dp)
.clickable {
onItemClicked(movieItem)
navController.navigate("movieDetails")
})
}
clickable is part of Modifier.So by the above code on item click we set the movie item to viewmodel,and called navController.navigate(“movieDetails”).
Now final thing to do is handle navigate movieDetails inside MainActivity.
For that create a rememberNavController and NavHost.
NavHost is responsible for defining the start destination and for handling navigate apis.So we define Two composable function with route address,So navhost can handle it on navigate call.Creating the NavHost
requires the NavController
previously created via rememberNavController()
and the route of the starting destination of your graph.
Sample code is added below.
setContent {
val navController = rememberNavController()
MVVMJetPackComposeSampleTheme {
NavHost(navController = navController, startDestination = "trendingMovieList") {
composable("trendingMovieList") {
Surface(color = MaterialTheme.colors.background) {
MainList(navController = navController, mainViewModel = mainViewModel)
}
}
composable("movieDetails") {
MovieDetails(mainViewModel.clickedItem)
}
}
}
Full source code is available in github.
Happy Reading… Happy Coding…
Reference