Build MVVM Application with Kotlin—Part1:Getting Started

ditclear
AndroidPub
Published in
4 min readJan 19, 2020

--

First: what is MVVM?

MVVM is the abbreviation of Model-View-ViewModel, which is another architectural pattern different from MVC and MVP.

Compared with MVP, MVVM has no extra callbacks. Using the Databinding framework, you can bind the data in the ViewModel to the UI, so that developers can only change the UI by updating the data in the ViewModel.

Let’s talk about the role of each

  • Model: Responsible for providing data sources to the ViewModel, including entity classes, network requests, and local storage
  • ViewModel: Processes the data provided by the Model layer according to the needs of the View layer, and binds to the corresponding UI through DataBinding.
  • View: Activity, Fragment, layout.xml, Adapter, custom View, etc., responsible for connecting the three.

A basic example

Here we define an entity Animal.kt.

/**
* Description:Animal
*
* Created by ditclear on 2017/11/18.
*/
data class Animal(val name:String,var shoutCount:Int)

See what we need to do. .

It has two parameters name and shoutCount. name represents the name of the animal, and shoutCount indicates how many times it was called.

todo
  1. Display required information
  2. When shout button is clicked, shouCount + 1 and update information

Very simple, just a few lines of code, let’s see how to do it without any architecture.

class AnimalActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.animal_activity)
val animal=Animal("dog",0) findViewById<TextView>(R.id.info_tv).text="${animal.name} barked ${animal.shoutCount} times.." findViewById<View>(R.id.action_btn).setOnClickListener {
animal.shoutCount++
findViewById<TextView>(R.id.info_tv).text="${animal.name} barked ${animal.shoutCount} times.."
}
}
}

Let’s take a look at how MVVM handles it to show the difference Compared to the former, we need to create a corresponding AnimalViewModel for AnimalActivity.

/*** Description:AnimalViewModel* @param animal :model (M in MVVM), responsible for providing the        *data to be processed in the ViewModel* Created by ditclear on 2017/11/17.*/class AnimalViewModel(val animal: Animal){//////////////////data//////////////val info= ObservableField<String>("${animal.name} barked ${animal.shoutCount} times..")//////////////////binding//////////////fun shout(){animal.shoutCount++info.set("${animal.name} barked ${animal.shoutCount} times..")}}

Then link the three in AnimalActivity.kt in the View layer

class AnimalActivity : AppCompatActivity() {

lateinit var mBinding : AnimalActivityBinding
lateinit var mViewMode : AnimalViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding=DataBindingUtil.setContentView(this,R.layout.animal_activity)
//////model
val animal= Animal("dog", 0)
/////ViewModel
mViewMode= AnimalViewModel(animal)
////binding
mBinding.vm=mViewMode
}
}

The directory architecture now looks like this:

Databinding strengthens the position of layout files in Android, and many display and click events are processed in XML.

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">  <data>  <!--Required viewModel, injected via mBinding.vm = mViewMode-->    <variable      name="vm"      type="io.ditclear.app.viewmodel.AnimalViewModel"/>
</data>
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context="io.ditclear.app.view.AnimalActivity">
<TextView android:id="@+id/info_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{vm.info}" tools:text="dog1 barked 2 times.." android:layout_marginBottom="24dp" android:layout_gravity="center"/>
<Button android:id="@+id/action_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAllCaps="false" android:text="shout" android:layout_marginTop="24dp" android:layout_gravity="center" android:onClick="@{()->vm.shout()}"/>
</FrameLayout></layout>

You can see that android: text = "@ {vm.info}" andandroid: onClick = "@ {()-> vm.shout ()}" call the variables and methods in viewModel respectively.

So the approximate process is

  • The user clicks the button and calls the shout method of AnimalViewModel
  • The ViewModel updates the shoutCount and info data, and then automatically updates the UI with the binding

The process is simple, but it reflects the idea of MVVM, and some people will say, is n’t there so much more code than the former?

Well, it does have one more file, but it does focus separation and data-driven UI.

In google words

principles

Another benefit is that you can do unit testing. Pure Kotlin code can be written comfortably, and it can ensure the correctness of the data. Compared to the run app, which takes more than ten seconds, or minutes, or ten minutes, a unit test is run in milliseconds, which is very efficient.

The end

GitHub link: https://github.com/ditclear/MVVM-Android

This is the first part of Build MVVM Application with Kotlin, and it is an introductory article, so it is very simple. I introduce the concept and basic writing of MVVM. In the second part, I will add retrofit network requests and Rxjava to talk about how to better handle network data And binding life cycle.

--

--