MVVM框架的搭建(二)——專案搭建

yang0range發表於2018-10-10

介紹完背景以及初衷之後,我們開始搭建MVVM的框架,這一部分我們進行簡單的搭建,瞭解MVVM架構的基本結構。

MVVM框架的搭建(一)——背景

MVVM框架的搭建(二)——專案搭建

MVVM框架的搭建(三)——網路請求

建立新專案

首先建立一個新的專案,在根目錄下建立一個config.gradle如圖

MVVM框架的搭建(二)——專案搭建
config.gradle用於配置專案中各種lib引用和版本號控制

/**
 * config.gradle用於配置專案中各種lib引用和版本號控制
 *
 * [module_*] 各module版本號及applicationId控制
 * 如需在各個module中升級更新版本號,請使用 module_[modulename]*的命名規則
 *
 * [project.ext.dependVersion] 中建立各個依賴庫的版本號控制,需在類庫名稱後增加‘_version’
 *
 * [類庫maven地址] 中建立各個類庫的maven地址,同一類庫需要引用多個類時,可以使用陣列,要確保類庫引用不重複
 *
 * [專案依賴列表] 中建立可以直接讓module引用的依賴列表,以Deps結尾,原則上以類庫功能分類,比如網路庫,圖片處理庫
 * 儘量不要以類庫本身的名字命名依賴列表
 *
 * 各個module中引用類庫時儘量使用專案依賴列表中的專案,不要直接使用類庫地址中的專案
 *
 * 需要新增新的類庫時,先查詢本列表和專案中是否已引用類似功能的類庫,儘量不要新增重複功能的類庫
 */
project.ext {
    compileSdkVersion = 27
    buildToolsVersion = '27.0.3'
    minSdkVersion = 16
    targetSdkVersion = 27

    //主app
    module_appApplicationId = 'yang.cehome.com.mvvmdemo'
    module_appVersionCode = 0001
    module_appVersionName = '1.0.0'
    module_appName = 'MVVM'

    //引用類庫的版本號
    dependVersion = [
            kotlin_version : '1.2.51',
            support_version: '27.1.1'
    ]

    //*************************類庫maven地址**************************
    kotlin_base = [kotlin_stdlib_jdk8: "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$dependVersion.kotlin_version"]
    supportLibs = [
            design      : "com.android.support:design:$dependVersion.support_version",
            appcompat_v7: "com.android.support:appcompat-v7:$dependVersion.support_version",
            constraint  : 'com.android.support.constraint:constraint-layout:1.1.3']
    //********************專案依賴列表**********************
    kotlinDeps = [kotlin_base.values()]
    supportDeps = [supportLibs.values()]
}
複製程式碼

然後再build.gradle我們引用相應的library庫

MVVM框架的搭建(二)——專案搭建
使用的時候需要注意的地方
MVVM框架的搭建(二)——專案搭建
MVVM框架的搭建(二)——專案搭建

依賴方法

AndroidStudio升級到3.0之後,gradle版本也隨之升級到了3.0.0版本。 在這之後,大家可能注意依賴的方式發生了一些變化,在這裡簡單介紹一下

依賴方式

寫在前面

現在MVC MVP MVVM框架的介紹很多,網上一搜一大堆就不著重介紹了。 之前用MVP重新寫的框架,但是也遇到了很多不方便的地方,所以這次我們著重介紹MVVM框架 這裡開始使用kotlin,並遵循google的App開發架構指南,才找到一種較好的構建MVVM應用程式的方式 首先:什麼是MVVM? MVVM是Model-View-ViewModel的簡寫,是有別於MVC和MVP的另一種架構模式。 相比於MVP,MVVM沒有多餘的回撥,利用Databinding框架就可以將ViewModel中的資料繫結到UI上,從而讓開發者只需要更新ViewModel中的資料,就可以改變UI。

再來講一下分別的作用 ● Model層:負責提供資料來源給ViewModel,包含實體類,網路請求和本地儲存等功能 ● ViewModel:將Model層提供的資料根據View層的需要進行處理,通過DataBinding繫結到相應的UI上 ● View:Activity、Fragment、layout.xml、Adapter、自定義View等等,負責將三者聯絡起來。

另一個好處就是可以做單元測試,純的kotlin程式碼寫著再舒服不過,而且可以保證資料的正確性。相比於run app需要十幾秒或者幾分鐘、十幾分鍾,run 一次單元測試是以毫秒記的,效率是很可觀的。

程式碼實現

首先我們建立一個類

/**
 * @author yangzc
 *	@data 2018/9/6 13:58
 *	@desc
 *
 */
class Onclick(val who: String, val count: Int)
複製程式碼
以前我們寫一個點選事件的程式碼大概
佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="yang.cehome.com.mvvmdemo.MainActivity">

    <Button
        android:id="@+id/bt_onclick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="onclick"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="100dp"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
複製程式碼
在Activity當中是這麼實現的
package yang.cehome.com.mvvmdemo

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val onclik = Onclick("my", 0)
        tv_count.text = "${onclik.who}點選了${onclik.count}次"
        bt_onclick.setOnClickListener(View.OnClickListener {
            onclik.count++
            tv_count.text = "${onclik.who}點選了${onclik.count}次"
        })
    }
}
複製程式碼

就實現了我們平時經常寫的一段點選事件並且顯示的一段程式碼 然而 我們要用MVVM框架顯然就不是這麼寫的了 首先我們看一下架構

MVVM框架的搭建(二)——專案搭建
根據我們的這個結構圖 我們簡單闡述一下 各個模組的作用

Model層:負責提供資料來源給ViewModel,包含實體類,網路請求和本地儲存等功能 ViewModel層:將Model層提供的資料根據View層的需要進行處理,通過DataBinding繫結到相應的UI上 View層:Activity、Fragment、layout.xml、Adapter、自定義View等等,負責將三者聯絡起來 簡單的介紹了一下MVVM之後,建立專案之後,看一下結構

包結構

基礎Demo

下面我們就根據我們之前說的簡單寫一個Demo 首先看一下包的結構 DataBindingUtil.setContentView 這個函式做了三步操作:

  • inflate操作,建立佈局檔案對應的view對像
  • setContentView操作,將view加入window
  • bind操作,建立ActivityXxxBinding 對像 bind操作最終呼叫了ActivityXxxBinding.bind(view, bindingComponent)操作,然後呼叫了: new ActivityXxxBinding(bindingComponent, view) 建立了ActivityXxxBinding 對像。 //啟用資料繫結 dataBinding{ enabled = true } 我們看看佈局檔案 其實 我們可以看到在MVVM當中佈局檔案的作用有所加強,不僅僅是構造一個UI效果。
<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <!--需要的viewModel,通過mBinding.vm=mViewMode注入-->
        <variable
            name="vm"
            type="yang.cehome.com.mvvmdemo.viewmodel.OnclikViewModel" />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.MainActivity">


        <Button
            android:id="@+id/bt_onclick"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->vm.click()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="來點一下試試" />

        <TextView
            android:id="@+id/tv_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="100dp"
            android:text="@{vm.info}"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="點了0次" />

    </android.support.constraint.ConstraintLayout>
</layout>
複製程式碼

值得注意的幾點:

1.最外層增加layout標籤 2.增加了一個data標籤 這個標籤是我們的ViewModel通過繫結注入的 3.在每個控制元件上增加相應的方法 下面看看M層的程式碼 提供給ViewModel層的資料

package yang.cehome.com.mvvmdemo.model

/**
 * @author yangzc
 *	@data 2018/9/6 13:58
 *	@desc 資料來源Model(MVVM 中的V),負責提供ViewModel中需要處理的資料
 *
 */
class Onclick(val who: String, var count: Int)
複製程式碼

下面我們在看看ViewModel層 這裡主要承擔了資料處理功能 並負責提供給View層資料 ViewModel是用來儲存和管理UI相關的資料。

package yang.cehome.com.mvvmdemo.viewmodel

import android.databinding.ObservableField
import yang.cehome.com.mvvmdemo.model.Onclick

/**
 * @author yangzc
 *	@data 2018/9/6 16:59
 *	@desc 處理資料V(MVVM 中的VM),負責提供View中需要處理的資料
 *
 */
class OnclikViewModel(val onlick: Onclick) {
    /******data******/
    val info = ObservableField<String>("\"${onlick.who}點選了${onlick.count}次\"")

    /******binding******/
    fun click() {
        onlick.count++
        info.set("\"${onlick.who}點選了${onlick.count}次\"")
    }

}
複製程式碼

最後我們看看View層,也就是我們Activity和Fragment

package yang.cehome.com.mvvmdemo.view

import android.databinding.DataBindingUtil
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import yang.cehome.com.mvvmdemo.R
import yang.cehome.com.mvvmdemo.databinding.ActivityMainBinding
import yang.cehome.com.mvvmdemo.model.Onclick
import yang.cehome.com.mvvmdemo.viewmodel.OnclikViewModel

/**
 * MVVM 當中的一個V層 將三者聯絡起來
 */
class MainActivity : AppCompatActivity() {
    private lateinit var mBinding: ActivityMainBinding
    private lateinit var mViewMode: OnclikViewModel


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

        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        /////model
        val onclick = Onclick("me", 0)
        ///ViewModel
        mViewMode = OnclikViewModel(onclick)
        ///binding
        mBinding.vm = mViewMode
    }
}
複製程式碼

以上就是一個簡單的MVVM的框架

實現效果

專案地址

github.com/yang0range/…

相關文章