Jetpack Compose With MVVM

Kushal Dave
4 min readDec 1, 2019

Ever since i worked on flutter around 2 years back i have been a big fan of declarative UI so naturally i was overjoyed when i heard about Jetpack Compose in Google I/O 2019.. recently i downloaded android studio canary to try out its developer preview and it is every bit of what i expected and more ❤

This purpose of this article is to demonstrate the usage of Jetpack Compose with MVVM Architecture ,we will create a simple list of users (from local data) and update its values but before we get started with the code here are some quick pointers

  • “@Composable” is annotated before a function for declaring it UI function
  • Annotating “@model” before a model class will automatically update the corresponding ui when the value of that model changes
  • The flow of data is always top to bottom so in mvvm the data will come from Repository -> viewModel -> activity and from activity stateModel will be updated which will update the UI
  • Now for handling events of from the UI like button click ,we shall use lambdas to update the activity of the occurring event , from activity the flow will be activity -> viewModel -> repository and from repository the data will be send back by the flow mentioned in above point
  • This app is just for demonstration purpose so i have tried to keep the code minimum and in order to do so i have not used repository pattern and static data is generated in viewModel itself

If you want to code along with the article you will need to setup the project with android studio canary(4.0) you can download it here

Once it is setup create a new project and select empty compose activity as project template

Now lets start with coding

First of all we will need a simple user model as we are creating a list of users, create a new class called UserModel

class UserModel(name:String,surName:String,job:String) {
var userName:String = name
var userSurName:String = surName
var userJob:String = job
}

now lets create an Model class to hold list of UserModels , We will need to notify ui when list is updated so we will annotate this model with “@model”

import androidx.compose.Model

@Model
class UsersState(var users:ArrayList<UserModel> = ArrayList())

Now create an object class to hold composable functions for UI , our function will take UserState as a parameter , one thing to note here is that we can use regular Kotlin code in composable functions to achieve our tasks

import androidx.compose.Composable
import androidx.ui.core.Text
import androidx.ui.core.dp
import androidx.ui.foundation.VerticalScroller
import androidx.ui.graphics.Color
import androidx.ui.layout.Column
import androidx.ui.layout.FlexColumn
import androidx.ui.layout.Row
import androidx.ui.layout.WidthSpacer
import androidx.ui.material.*

object UsersListUi {

@Composable
fun addList(state: UsersState) {
MaterialTheme {
FlexColumn {
inflexible {
// Item height will be equal content height
TopAppBar( // App Bar with title
title = { Text("Users") }
)
VerticalScroller {
Column {
state.users.forEach {
Column {
Row {
Text(text = it.userName)
WidthSpacer(width = 2.dp)
Text(text = it.userSurName)
}
Text(text = it.userJob)

}
Divider(color = Color.Black, height = 1.dp)

}
}
}
}

}
}

}


}

Here in above code we are using for loop to display list which is not very efficient , for coding it more efficiently google teased something called ScrollingList… currently as of writing this article it is not yet part of jetpack compose but if you are reading it sometime in future try to replace this line with the for loop , if ScrollingList is released it should work or else you will have to wait

//state.users.forEach {
ScrollingList(state.users) {it ->

Now lets create a viewModel that will contain business logic , we will use livedata for list of userModels

add these dependency in your build.gradle file

implementation 'android.arch.lifecycle:runtime:1.1.1'
implementation 'android.arch.lifecycle:extensions:1.1.1'

create a new file for UsersListViewModel

import androidx.lifecycle.MutableLiveData

class UsersListViewModel {

private val usersList: MutableLiveData<ArrayList<UserModel>> by lazy {
MutableLiveData<ArrayList<UserModel>>()
}
private val users:ArrayList<UserModel> = ArrayList()
fun addUsers(){
users.add(UserModel("jon","doe","android developer"))
users.add(UserModel("john","doe","flutter developer"))
users.add(UserModel("jonn","dove","ios developer"))
usersList.value = users
}

fun getUsers():MutableLiveData<ArrayList<UserModel>>{
return usersList
}
}

Now lets put everything together in MainActivity

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.ui.core.setContent

class MainActivity : AppCompatActivity() {
private val usersState: UsersState = UsersState()
private val usersListViewModel:UsersListViewModel = UsersListViewModel()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

usersListViewModel.getUsers().observe(this, Observer {
usersState.users.addAll(it)
})
usersListViewModel.addUsers()
setContent {
UsersListUi.addList(usersState)
}
}

}
  • Run the app

All the code up until now is available here

Those who want to take it further and add and remove data from the list, here is what you can do

in UsersListUi class

change constructor of addList method to accept 2 lamdas to notify activity on button click

@Composable
fun addList(state: UsersState, onAddClick: () -> Unit, onRemoveClick: () -> Unit) {

then add 2 buttons and invoke lamdas on their click

FlexRow() {
expanded(flex = 1f) {
Button(
text = "add",
onClick = { onAddClick.invoke() },
style = OutlinedButtonStyle()
)

}
expanded(flex = 1f) {
Button(
text = "sub",
onClick = { onRemoveClick.invoke() },
style = OutlinedButtonStyle()
)
}
}

From MainActivity send lamdas to the function

UsersListUi.addList(
usersState,
onAddClick = { usersListViewModel.addNewUser() },
onRemoveClick = { usersListViewModel.removeFirstUser() })

Here when a button will be clicked it will invoke the lamda which will notify the activity and activity will call methods from viewModel to update the data in list

Thank you for reading! Feel free to say hi or share your thoughts on Twitter @that_kushal_guy or in the responses below!

Also checkout my other article on using Machine Learning with Android

--

--