Understanding MVVM Architecture in Jetpack Compose

Gopal GuptaGopal Gupta
3 min read

Introduction :->

Hey Android Enthusiasts🙋🏻‍♂️,

In the evolving landscape of Android development, adopting the right architecture is crucial for building maintainable and scalable applications. One of the most recommended patterns is MVVM (Model-View-ViewModel). With the advent of Jetpack Compose, it's even more critical to understand how to implement MVVM effectively. In this article, we'll explore how MVVM architecture works with Jetpack Compose, ensuring your apps are robust and easy to manage.

What is MVVM?

MVVM divides an application into three main components:

  1. Model: Represents the data and business logic of the application. It is responsible for handling data operations, such as fetching data from a database or a network.

  2. View: The UI layer that displays the data to the user. In Jetpack Compose, this is represented by Composable functions.

  3. ViewModel: Acts as a bridge between the Model and the View. It manages the UI-related data in a lifecycle-conscious way, ensuring that the data survives configuration changes such as screen rotations.

Setting Up MVVM in Jetpack Compose

Let's walk through a simple example to illustrate how MVVM works in Jetpack Compose.

Step 1: Adding Dependencies

First, ensure that you have the necessary dependencies in your build.gradle file:

dependencies {
    implementation "androidx.compose.ui:ui:1.2.0"
    implementation "androidx.compose.material:material:1.2.0"
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0"
    implementation "androidx.activity:activity-compose:1.3.1"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
}

Step 2: Creating the Model

The Model represents the data. For simplicity, let's create a data class and a repository to handle data operations.

data class User(val id: Int, val name: String)

class UserRepository {
    fun getUser(userId: Int): User {
        // In a real application, this might fetch data from a database or a network
        return User(userId, "John Doe")
    }
}

Step 3: Creating the ViewModel

The ViewModel manages the UI-related data. It fetches data from the repository and exposes it to the View.

class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> get() = _user

    fun loadUser(userId: Int) {
        _user.value = userRepository.getUser(userId)
    }
}

class UserViewModelFactory(private val userRepository: UserRepository) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(UserViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return UserViewModel(userRepository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

Step 4: Creating the View

In Jetpack Compose, the View is defined using Composable functions. The ViewModel is integrated using viewModel from androidx.lifecycle.viewmodel.compose.

@Composable
fun UserScreen(userId: Int, userViewModel: UserViewModel = viewModel()) {
    val user by userViewModel.user.observeAsState()

    LaunchedEffect(Unit) {
        userViewModel.loadUser(userId)
    }

    user?.let {
        Text(text = "User: ${it.name}")
    } ?: run {
        CircularProgressIndicator()
    }
}

Step 5: Wiring Everything Together

Finally, set up your activity to use the Composable function and ViewModel.

class MainActivity : ComponentActivity() {
    private val userRepository = UserRepository()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val userViewModel: UserViewModel = viewModel(factory = UserViewModelFactory(userRepository))
            UserScreen(userId = 1, userViewModel = userViewModel)
        }
    }
}

Conclusion

MVVM is an effective architectural pattern that helps manage the complexity of modern Android applications. By separating the data (Model), UI logic (ViewModel), and UI representation (View), you can create modular, testable, and maintainable applications. Jetpack Compose seamlessly integrates with MVVM, making it easier to build reactive UIs. As Compose continues to evolve, its integration with MVVM and other architectural patterns will only get stronger, offering developers a robust toolkit for building Android applications.

I hope you found this article insightful! If you did, feel free to share it – sharing is caring, after all.

Thank you for reading! 😄

Connect with me on LinkedIn or visit my website to learn more about my work 👨🏻‍💻.

Happy coding!

0
Subscribe to my newsletter

Read articles from Gopal Gupta directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gopal Gupta
Gopal Gupta

Android Developer