Android 中的mvvm,Androidmvvm

來源:互聯網
上載者:User

Android 中的mvvm,Androidmvvm

摘要:我們來瞭解一下MVVM模式與Databinding ,MVVM是一種模式,Databinding 是一種架構。DataBinding是一個實現資料和UI綁定的架構。而ViewModel和View可以通過DataBinding來實現單向綁定和雙向繫結,這套UI和資料之間的動態監聽和動態更新的架構Google已經幫我們做好了。MVVM的思想和MVP類似。在MVVM模式中ViewModel和View是用綁定關係來實現的。

首先我們看一下mvvm中view、model、viewmodel三者是如何分工:

View簡單地說不做任何商務邏輯、不涉及處理資料、操作資料,把UI和資料分離。

Model: 實體模型,同時包括Retrofit 的Service ,ViewModel 可以根據Model 擷取一個Bean的Observable<Bean>( RxJava ),然後             做一些資料轉換操作和映射到ViewModel 中的一些欄位,最後把這些欄位綁定到View層上。

ViewModel負責完成View於Model間的互動,負責商務邏輯。ViewModel層做的事情剛好和View層相反,ViewModel 只做和商務邏輯和                 業務資料相關的事,不做任何和UI、控制項相關的事,ViewModel 層不會持有任何控制項的引用,更不會在ViewModel中通過UI                 控制項的引用去做更新UI的事情。ViewModel就是專註於業務的邏輯處理,操作的也都是對資料進行操作,這些個資料來源綁定                   在相應的控制項上會自動去更改UI。記住:viewModel不做和UI相關的事。

我們在看看它的優勢:

  • 低耦合度:在MVVM模式中,資料是獨立於UI的,而ViewModel只負責處理和提供資料,UI想怎麼處理資料都是由UI自己決定的,ViewModel 不涉及任何和UI相關的事也不持有UI控制項的引用,即使控制項改變,ViewModel 幾乎不需要更改任何代碼。

  • 更新UI:在MVVM中,我們可以在背景工作執行緒中直接修改View Model的資料(只要資料是安全執行緒的),剩下的就不需要你去關心,資料繫結架構會幫我們搞定。

  • 可複用性:一個View Model複用到多個View中,同樣的一份資料,用不同的UI去做展示,對於版本迭代頻繁的UI改動,只需更換View層就行,對於如果想在UI上的做AbTest 更是方便的多。

  • 單元測試:View Model裡面是資料和商務邏輯,View中關注的是UI,這樣做測試是很方便的,完全沒有彼此的依賴,不管是UI的單元測試還是商務邏輯的單元測試,都是低耦合的。

view與viewmodel的協作:

Model 是通過Retrofit 去擷取網路資料的,返回的資料是一個Observable<Bean>( RxJava ),Model 層其實做的就是這些。那麼ViewModel 做的就是通過傳參數到Model層擷取到網路資料(資料庫同理)然後把Model的部分資料對應到ViewModel的一些欄位(ObservableField),並在ViewModel 保留這個Model的引用。

三者的關係:

 

 

 看完上面的圖,相信大家有了瞭解,接下來我們看看在代碼中的實現:

首先在項目裡添加依賴:

     classpath 'com.android.tools.build:gradle:1.2.3'

     classpath 'com.android.databinding:dataBinder:1.0-rc0'

 

這裡用到 Data Binding,所以在Data Binding的模組添加外掛程式,在build裡添加。

      apply plugin: 'com.android.databinding'

接下來我們看一下它的布局檔案:

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="使用者名稱:"/>            <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="密碼:"/>            <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="登入"/>        <Button            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="註冊"/>    </LinearLayout></layout>

相信大家看到了,我們的根節點變成了layout,還有一個data節點。

要實現 MVVM 的 ViewModel 就需要把資料與UI進行綁定,data 節點就為此提供了一個橋樑,我們先在data 中聲明一個 variable,這個變數會為 UI 元素提供資料(例如 TextView 的 android:text),然後在代碼中把”後台”資料與這個 variable 進行綁定。

大家看一下variable

在 data 節點中聲明一個變數viewModel,這個name可以隨便起。其中 type 屬性就是我們在 Java 檔案中定義的ViewModel 類。

在 build.gradle 中添加的那個外掛程式 - com.android.databinding會根據xml檔案的名稱 Generate一個繼承自 ViewDataBinding 的類。

例如,這裡 xml 的檔案名稱叫 activity_main.xml,那麼產生的類就是 ActivityMainBinding

接下來我們綁定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));    }

綁定之後,我們在布局裡就可以直接使用。看test

是不是很簡單,哈哈。

大家如果對mvvm感興趣,不妨可以深入研究一下,也可以把它跟mvp、mvc做一下對比。相信不久,你會愛上它的。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.