Movies Database
Modifying the view model to use real data
First, we need to provide a MovieRepository
for the view model to use.
We do this via constructor injection, passing it as a parameter to the constructor. When we create an instance of the view model, we'll need to pass one in. Now that the view model knows about a repository, we can get data from that repository by delegation.
show in full file app/src/main/java/com/androidbyexample/compose/movies/MovieViewModel.kt
// ...
//class MovieViewModel: ViewModel() {
class MovieViewModel(
private val repository: MovieRepository,
): ViewModel(), MovieRepository by repository {
private var screenStack = listOf<Screen>(MovieList)
set(value) {
// ...
}
Using MovieViewModel: MovieRepository by repository
like this generates implementation functions
and properties for those defined in MovieRepository
that call the functions in the passed-in
repository. This is similar to explicitly writing code like
class MovieViewModel(
private val repository: MovieRepository,
): ViewModel() {
val moviesFlow = repository.moviesFlow
suspend fun getMovieWithCast(id: String) =
repository.getMovieWithCast(id)
suspend fun insert(actor: ActorDto) {
repository.insert(actor)
}
...
}
If any of the functions need modification, you can override them.
Note
At this point the code will no longer compile, as we've broken the way movies are exposed to the UI.
All code changes
CHANGED: app/src/main/java/com/androidbyexample/compose/movies/MovieViewModel.kt
package com.androidbyexample.compose.movies
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.androidbyexample.compose.movies.repository.MovieRepository
import com.androidbyexample.compose.movies.screens.MovieList
import com.androidbyexample.compose.movies.screens.Screen
//class MovieViewModel: ViewModel() {
class MovieViewModel(
private val repository: MovieRepository,
): ViewModel(), MovieRepository by repository {
private var screenStack = listOf<Screen>(MovieList)
set(value) {
field = value
currentScreen = value.lastOrNull()
}
var currentScreen by mutableStateOf<Screen?>(MovieList)
private set
fun pushScreen(screen: Screen) {
screenStack = screenStack + screen
}
fun popScreen() {
screenStack = screenStack.dropLast(1)
}
val movies: List<Movie> = listOf(
Movie("The Transporter", "Jason Statham kicks a guy in the face"),
Movie("Transporter 2", "Jason Statham kicks a bunch of guys in the face"),
Movie("Hobbs and Shaw", "Cars, Explosions and Stuff"),
Movie("Jumanji - Welcome to the Jungle", "The Rock smolders"),
)
}