Build MVVM Application with Kotlin—Part1:Getting Started
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 theView
layer, and binds to the corresponding UI throughDataBinding
. - 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.
- Display required information
- 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 ofAnimalViewModel
- The ViewModel updates the
shoutCount
andinfo
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
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.