MVVM network framework building

MVVM framework construction (a) – background

The construction of MVVM framework (ii) – project construction

The construction of MVVM framework (three) — network request

MVVM data persistence (I) — ROOM integration

MVVM data persistence (2) — use of ROOM

Before, we briefly introduced the composition of the MVVM framework and build a basic demo, but network request is our daily development, a very basic and necessary part, let’s comb the MVVM with network request.

First we integrate the related dependencies in the project
/** * config.gradle is used to configure lib references and version control for projects ** [module_*] Module version and applicationId control * Please use module_ [modulename] * * * naming rules [project. Ext dependVersion] created in all dependent libraries of version control, Create maven addresses for each class library by adding '_version' * * [class library maven address] to the name of the class library. If the same class library needs to reference more than one class, you can use an array. Make sure that the class library reference does not duplicate the dependency list created in * * [project dependency list] that can be referenced directly by module. * Do not name the dependency list after the name of the class library * * Use the item in the project dependency list when referring to the class library in each module. Do not use the item directly in the address of the class library. * * When adding a new class library, Check this list and the project to see if there are libraries that reference similar functionality */ project.ext {compileSdkVersion = 27 buildToolsVersion ='27.0.3'MinSdkVersion = 16 targetSdkVersion = 27 // Main 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',
            databinding_version: '3.2.0 - alpha10',
            retrofit2_version  : '2.3.0,
            gson_version       : '2.8.5',
            rxandroid_version  : '2.1.0',
            rxjava_version     : '2.2.2'] / / * * * * * * * * * * * * * * * * * * * * * * * * * class library maven address * * * * * * * * * * * * * * * * * * * * * * * * * * 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. The constraint, the constraint - layout: 1.1.3']

    databindingLibs = [databinding: "com.android.databinding:compiler:$dependVersion.databinding_version"]

    network = [
            retrofit           : "com.squareup.retrofit2:retrofit:$dependVersion.retrofit2_version",
            retrofit_converters: "com.squareup.retrofit2:converter-gson:$dependVersion.retrofit2_version",
            retrofit_adapters  : "com.squareup.retrofit2:adapter-rxjava2:$dependVersion.retrofit2_version"]

    gson = [gson: "com.google.code.gson:gson:$dependVersion.gson_version"]

    rxandroid = [rxandroid: "io.reactivex.rxjava2:rxandroid:$dependVersion.rxandroid_version"]

    rxjava = [rxjava: "io.reactivex.rxjava2:rxjava:$dependVersion.rxjava_version"] / / * * * * * * * * * * * * * * * * * * * * project depend on the list of * * * * * * * * * * * * * * * * * * * * * * kotlinDeps = [kotlin_base. Values ()] supportDeps = [supportLibs.values()] databindingDeps = [databindingLibs.values()] networkDeps = [network.values(), gson.values()] rxDeps = [rxandroid.values(), rxjava.values()] }Copy the code

We still take this unified management approach. Then we rely on engineering

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation project.ext.kotlinDeps
    implementation project.ext.supportDeps
    implementation project.ext.networkDeps
    implementation project.ext.rxDeps
    annotationProcessor  project.ext.databindingDeps
}
Copy the code
Code implementation

We added a package of remote and a package of Service class as shown in the figure

data class WeatherInfoData(
    val weatherinfo: Weatherinfo
)

data class Weatherinfo(
    val AP: String,
    val Radar: String,
    val SD: String,
    val WD: String,
    val WS: String,
    val WSE: String,
    val city: String,
    val cityid: String,
    val isRadar: String,
    val njd: String,
    val sm: String,
    val temp: String,
    val time: String
)
Copy the code

Now start writing the request

package yang.cehome.com.mvvmdemo.model.remote import io.reactivex.Single import retrofit2.http.GET import yang.cehome.com.mvvmdemo.model.data.WeatherInfoData /** * @author yangzc * @data 2018/9/11 18:13 * @desc WeatherService * */ interface WeatherService {// GET weather @get ("/data/sk/101190408.html")
    fun getWeatherInfo(): Single<WeatherInfoData>

}
Copy the code

So let’s start writing the ViewModel

package yang.cehome.com.mvvmdemo.viewmodel

import android.databinding.ObservableField
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import yang.cehome.com.mvvmdemo.model.data.WeatherInfoData
import yang.cehome.com.mvvmdemo.model.remote.WeatherService

/**
 * @author yangzc
 *	@data 2018/9/12 14:20
 *	@desc WeatherViewModel
 *
 */
class WeatherViewModel(val remote: WeatherService) {
    /******data******/
    val weatherinfo = ObservableField<String>()

    /******binding******/
    fun loadWeather() { remote.getWeatherInfo() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ t: WeatherInfoData? -> weatherinfo.set(t? .let { it.weatherinfo.toString() }) }, { t: Throwable? -> weatherinfo.set(t? .message ? :"error")}}}Copy the code

Let’s take a look at the code in the Activity

package yang.cehome.com.mvvmdemo.view import android.databinding.DataBindingUtil import android.os.Bundle import android.support.v7.app.AppCompatActivity import retrofit2.Retrofit import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory import retrofit2.converter.gson.GsonConverterFactory import yang.cehome.com.mvvmdemo.R import yang.cehome.com.mvvmdemo.databinding.ActivityMainBinding import yang.cehome.com.mvvmdemo.model.data.Onclick import yang.cehome.com.mvvmdemo.model.remote.WeatherService import yang.cehome.com.mvvmdemo.viewmodel.OnclikViewModel import yang.cehome.com.mvvmdemo.viewmodel.WeatherViewModel /** * MVVM One of the V layers connects the three */ class MainActivity:AppCompatActivity() {
    private lateinit var mBinding: ActivityMainBinding
    private lateinit var mViewMode: OnclikViewModel
    private lateinit var mViewMode2: WeatherViewModel


    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


        val remote = Retrofit.Builder()
                .baseUrl("http://www.weather.com.cn")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build().create(WeatherService::class.java)

        mViewMode2 = WeatherViewModel(remote)
        mBinding.vm = mViewMode
        mBinding.remote = mViewMode2
    }
}

Copy the code

We can see that the Activity takes on the role of the request network but the processing of the data is not represented here, and we can see that the action and display of the click are not represented here. Let me take a look at the layout file, and you can see how important the new structure is to the layout file

<? 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> <! Mbinding. vm=mViewMode --> <variable name="vm"
        type="yang.cehome.com.mvvmdemo.viewmodel.OnclikViewModel" />

        <variable
            name="remote"
            type="yang.cehome.com.mvvmdemo.viewmodel.WeatherViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".view.MainActivity">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp">

            <Button
                android:id="@+id/bt_onclick"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{()->vm.click()}"
                android:text="Give it a try." />

            <TextView
                android:id="@+id/tv_count"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/bt_onclick"
                android:layout_marginBottom="20dp"
                android:text="@{vm.info}"
                android:textSize="16sp"
                tools:text="Zero times." />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_marginTop="60dp">


            <Button
                android:id="@+id/bt_load"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{()->remote.loadWeather()}"
                android:text="Network access" />

            <TextView
                android:id="@+id/tv_load"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/bt_load"
                android:layout_marginBottom="50dp"
                android:text="@{remote.weatherinfo}"
                android:textSize="16sp"
                />

        </RelativeLayout>
    </LinearLayout>
</layout>
Copy the code

Of course, don’t forget to add Internet access at the end

   <uses-permission android:name="android.permission.INTERNET" />
Copy the code

And then we can see the effect

At this point, the completion of the MVVM framework, also completed the basic network request, for the MVVM framework has a deeper understanding, then the next to further optimize the framework, rich functions.

The project address

Github.com/yang0range/…