Mvvm and Androidmvvm in Android
Abstract: Let's take a look at the MVVM mode and Databinding. MVVM is a mode and Databinding is a framework. DataBinding is a framework for binding data to the UI. ViewModel and View can achieve one-way binding and two-way binding through DataBinding. This framework of dynamic monitoring and dynamic update between UI and data has already helped us do a good job. The idea of MVVM is similar to that of MVP. In MVVM mode, ViewModel and View are implemented by binding relationships.
First, let's take a look at the division of labor among view, model, and viewmodel in mvvm:
View:Simply put, the UI and data are separated without any business logic, data processing, and data operations.
Model:Entity Model, including the Service of adaptive fit. ViewModel can obtain the Observable <Bean> (RxJava) of a Bean Based on the Model, and then perform some data conversion operations and map some fields to the ViewModel, finally, bind these fields to the View layer.
ViewModel:Responsible for interaction between views and models and business logic. The ViewModel layer is just opposite to the View layer. ViewModel only performs business logic and business data, and does not do anything related to the UI and controls, the ViewModel layer does not hold any reference of the control, nor update the UI through the reference of the UI control in the ViewModel. ViewModel focuses on business logic processing, and operations are also performed on data. These data sources are bound to the corresponding controls and the UI is automatically changed. Remember: viewModel does not do anything related to the UI.
We are looking at its advantages:
Low coupling: In MVVM mode, data is independent from the UI, while ViewModel is only responsible for processing and providing data. The UI determines how to process data, viewModel does not involve any UI-related things or reference the UI control. Even if the control changes, ViewModel almost does not need to change any code.
UI update: In MVVM, we can directly modify the data of the View Model in the working thread (as long as the data is thread-safe), and you do not need to care about the rest, the data binding framework will help us solve this problem.
Reusability: A View Model is reused into multiple views. The same data is displayed using different UIS. For frequent version iterations, you only need to change the View layer. It is more convenient for you to perform AbTest on the UI.
- Unit test: The View Model contains data and business logic, and the View focuses on the UI. This test is very convenient and completely independent of each other, both UI unit testing and business logic unit testing are low coupling.
Collaboration between view and viewmodel:
The Model obtains network data through the adaptive fit. The returned data is an Observable <Bean> (RxJava). This is what the Model layer actually does. Then, ViewModel obtains network data by passing parameters to the Model layer (similarly, the database) and maps some data of the Model to some fields of ViewModel (ObservableField ), and keep the reference of this Model in ViewModel.
Relationship:
After reading the above figure, I believe you will understand it. Next let's look at the implementation in the Code:
First, add the dependency to the project:
Classpath 'com. android. tools. build: gradle: 1.2.3'
Classpath 'com. android. databinding: dataBinder: 1.0-rc0'
Data Binding is used here, So add a plug-in the Data Binding module and add it in build.
Apply plugin: 'com. android. databinding'
Next, let's take a look at its layout file:
Activity_main.xml
<? Xml version = "1.0" encoding = "UTF-8"?> <Layout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: app = "http://schemas.android.com/apk/res-auto"> <data> <variable name = "viewModel" type = "cn. saiz. mvvmhello. mainViewModel "/> </data> <LinearLayout android: layout_width =" match_parent "android: layout_height =" match_parent "android: orientation =" vertical "> <LinearLayout android: layout_width = "match_parent" android: layout_height = "wrap_content" android: orientation = "horizontal" android: layout_marginTop = "10dp"> <TextView android: layout_width = "wrap_content" android: layout_height = "match_parent" android: textSize = "16sp" android: textColor = "@ android: color/black" android: gravity = "center" android: text = "username: "/> <EditText android: layout_width =" match_parent "android: layout_height =" wrap_content "android: hint =" simon "android: text =" @ = {viewModel. userName} "app: addTextChangedListener =" @ {viewModel. userNameEditTextWatcher} "/> </LinearLayout> <LinearLayout android: layout_width =" match_parent "android: layout_height =" wrap_content "android: orientation =" horizontal "android: layout_marginTop = "10dp"> <TextView android: layout_width = "wrap_content" android: layout_height = "match_parent" android: textSize = "16sp" android: textColor = "@ android: color/black "android: gravity =" center "android: text =" Password: "/> <EditText android: layout_width =" match_parent "android: layout_height =" wrap_content "android: hint = "123456" android: text = "= {viewModel. passWord} "app: addTextChangedListener =" @ {viewModel. passwordEditTextWatcher} "/> </LinearLayout> <Button android: layout_width =" match_parent "android: layout_height =" wrap_content "android: onClick =" @ {viewModel. login} "android: text =" login "/> <Button android: layout_width =" match_parent "android: layout_height =" wrap_content "android: text = "register"/> </LinearLayout> </layout>
I believe you can see that our root node becomes layout, and there is a data node.
To implement the MVVM ViewModel, You need to bind the data to the UI,data
The node provides a bridge for this purpose.data
Declare one invariable
, This variable will provide data for the UI element (for example, the android: text of TextView), and then the "background" data andvariable
.
Let's take a look at variable.
Indata
A viewModel variable is declared in the node. This name can be set as needed. Wheretype
Attribute is the ViewModel class defined in the Java file.
Plug-in added in build. gradle-com.android.databinding
Based on the name of the xml fileGenerateAn inherited fromViewDataBinding
.
For example, the xml file name isactivity_main.xml
The generated class isActivityMainBinding
.
Next we Bind variable
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewDataBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setVariable(cn.saiz.mvvmhello.BR.viewModel, new MainViewModel(this)); }
After binding, we can use it directly in the layout. View test
Isn't it easy? haha.
If you are interested in mvvm, you may wish to study it in depth or compare it with mvp and mvc. I believe that you will soon fall in love with it.