MVVM架构 学习

MVVM架构是什么?

        Model-View-ViewModel,也就是MVVM架构是由MVP模式与WPF结合的应用方式发展演变过来的一种新型架构框架,立足于原有MVP框架并且糅合了WPF的新特性,MVVM 的核心是 ViewModel 层,负责转换 Model 中的数据对象来让数据变得更容易管理和使用,该层向上与视图层进行双向数据绑定,向下与 Model 层通过接口请求进行数据交互,起呈上启下作用。


模型示意图

模型还是根据主流的设计思路,使用分层设计的理念

分为View层,Model层以及ViewModel层

View层

视图层,也就是用户界面,主要由 HTML 和 CSS 来构建,而为了更方便地展现ViewModel层和Model层的数据,产生了很多前后端模板语言。许多的MVVM 框架如 KnockoutJS,Vue,Angular 等也都有自己用来构建用户界面的内置模板语言。

Model层

泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。

ViewModel层

ViewModel 层是由前端开发人员组织生成和维护的视图数据层。ViewModel 层所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的,而实际上我们平时生活中能够见到的View层,所获得的的数据是来自于ViewModel层,并非是Model层的数据,因此ViewModel类似于是一个中间商的作用,购房者所想要买到合适的房源,依赖的是中间商提供的信息,和房屋主没有任何的直接联系。


MVVM框架的主要应用场景

  1)针对具有复杂交互逻辑的前端应用

  2)提供基础的架构抽象

  3)通过Ajax数据持久化,保证前端用户体验

简单介绍一下关于Ajax方面的内容,Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术,也就意味着他能够提高搜索的效率,利用更少的资源获取到相同的可用信息。

这样MVVM的效益就体现出来了,能够很好地与Ajax进行结合,减少刷新整张页面,提高资源的利用率。


代码示例

Model

{"weatherinfo":{"city":"杭州","cityid":"101210101","temp1":"5℃","temp2":"20℃","weather":"晴转多云","img1":"n0.gif","img2":"d1.gif","ptime":"18:00"}}
public class WeatherData {
 
    private WeatherInfo weatherinfo;
 
    public WeatherInfo getWeatherinfo() {
        return weatherinfo;
    }
 
    public void setWeatherinfo(WeatherInfo weatherinfo) {
        this.weatherinfo = weatherinfo;
    }
}
public class WeatherInfo {
 
    private String city;
 
    private String cityid;
 
    private String temp1;
 
    private String temp2;
 
    private String weather;
 
    private String img1;
 
    private String img2;
 
    private String ptime;
 
    public String getCity() {
        return city;
    }
 
    public void setCity(String city) {
        this.city = city;
    }
 
    public String getCityid() {
        return cityid;
    }
 
    public void setCityid(String cityid) {
        this.cityid = cityid;
    }
 
    public String getTemp1() {
        return temp1;
    }
 
    public void setTemp1(String temp1) {
        this.temp1 = temp1;
    }
 
    public String getTemp2() {
        return temp2;
    }
 
    public void setTemp2(String temp2) {
        this.temp2 = temp2;
    }
 
    public String getWeather() {
        return weather;
    }
 
    public void setWeather(String weather) {
        this.weather = weather;
    }
 
    public String getImg1() {
        return img1;
    }
 
    public void setImg1(String img1) {
        this.img1 = img1;
    }
 
    public String getImg2() {
        return img2;
    }
 
    public void setImg2(String img2) {
        this.img2 = img2;
    }
 
    public String getPtime() {
        return ptime;
    }
 
    public void setPtime(String ptime) {
        this.ptime = ptime;
    }

ModelView

public class QueryWeatherViewModel {
 
    private static final String TAG = "QueryWeatherViewModel";
 
    public final ObservableBoolean loading = new ObservableBoolean(false);
 
    public final ObservableBoolean loadingSuccess = new ObservableBoolean(false);
 
    public final ObservableBoolean loadingFailure = new ObservableBoolean(false);
 
    public final ObservableField<string> city = new ObservableField<>();
 
    public final ObservableField<string> cityId = new ObservableField<>();
 
    public final ObservableField<string> temp1 = new ObservableField<>();
 
    public final ObservableField<string> temp2 = new ObservableField<>();
 
    public final ObservableField<string> weather = new ObservableField<>();
 
    public final ObservableField<string> time = new ObservableField<>();
 
    private Call<weatherdata> mCall;
 
    public QueryWeatherViewModel() {
 
    }
 
    public void queryWeather() {
        loading.set(true);
        loadingSuccess.set(false);
        loadingFailure.set(false);
 
        mCall = RetrofitManager.get()
                .create(QueryWeatherRequest.class)
                .queryWeather();
        mCall.enqueue(new Callback<weatherdata>() {
 
            @Override
            public void onResponse(Call<weatherdata> call, Response<weatherdata> response) {
                WeatherInfo weatherInfo = response.body().getWeatherinfo();
                city.set(weatherInfo.getCity());
                cityId.set(weatherInfo.getCityid());
                temp1.set(weatherInfo.getTemp1());
                temp2.set(weatherInfo.getTemp2());
                weather.set(weatherInfo.getWeather());
                time.set(weatherInfo.getPtime());
 
                loading.set(false);
                loadingSuccess.set(true);
            }
 
            @Override
            public void onFailure(Call<weatherdata> call, Throwable t) {
                if (call.isCanceled()) {
                    Log.i(TAG, "call is canceled.");
                } else {
                    loading.set(false);
                    loadingFailure.set(true);
                }
            }
        });
    }
 
    public void cancelRequest() {
        if (mCall != null) {
            mCall.cancel();
        }
    }
}

View

<?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>
 
        <import type="android.view.View" />
 
        <variable
            name="viewModel"
            type="com.github.cyc.mvvmdemo.weather.viewmodel.QueryWeatherViewModel" />
    </data>
 
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="@dimen/default_content_padding"
        tools:context="com.github.cyc.mvvmdemo.weather.activity.QueryWeatherActivity">
 
        <Button
            android:id="@+id/btn_query_weather"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="@string/query_weather"
            android:enabled="@{viewModel.loading ? false : true}"
            android:onClick="@{() -> viewModel.queryWeather()}" />
 
        <RelativeLayout
            android:id="@+id/vg_weather_info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/btn_query_weather"
            android:layout_marginTop="@dimen/query_weather_margin"
            android:visibility="@{viewModel.loadingSuccess ? View.VISIBLE : View.GONE}">
 
            <TextView
                android:id="@+id/tv_city"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textStyle="bold"
                android:text="@string/city" />
 
            <TextView
                android:id="@+id/tv_city_value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_city"
                android:layout_alignBottom="@id/tv_city"
                android:text="@{viewModel.city}"
                tools:text="杭州" />
 
            <TextView
                android:id="@+id/tv_city_id"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/tv_city"
                android:layout_marginTop="@dimen/query_weather_margin"
                android:textStyle="bold"
                android:text="@string/city_id" />
 
            <TextView
                android:id="@+id/tv_city_id_value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_city_id"
                android:layout_alignBottom="@id/tv_city_id"
                android:text="@{viewModel.cityId}"
                tools:text="101210101" />
 
            <TextView
                android:id="@+id/tv_temp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/tv_city_id"
                android:layout_marginTop="@dimen/query_weather_margin"
                android:textStyle="bold"
                android:text="@string/temperature" />
 
            <TextView
                android:id="@+id/tv_temp1_value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_temp"
                android:layout_alignBottom="@id/tv_temp"
                android:text="@{viewModel.temp1}"
                tools:text="5℃" />
 
            <TextView
                android:id="@+id/tv_tilde"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_temp1_value"
                android:layout_alignBottom="@id/tv_temp"
                android:text="@string/tilde" />
 
            <TextView
                android:id="@+id/tv_temp2_value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_tilde"
                android:layout_alignBottom="@id/tv_temp"
                android:text="@{viewModel.temp2}"
                tools:text="10℃" />
 
            <TextView
                android:id="@+id/tv_weather"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/tv_temp"
                android:layout_marginTop="@dimen/query_weather_margin"
                android:textStyle="bold"
                android:text="@string/weather" />
 
            <TextView
                android:id="@+id/tv_weather_value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_weather"
                android:layout_alignBottom="@id/tv_weather"
                android:text="@{viewModel.weather}"
                tools:text="晴" />
 
            <TextView
                android:id="@+id/tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/tv_weather"
                android:layout_marginTop="@dimen/query_weather_margin"
                android:textStyle="bold"
                android:text="@string/release_time" />
 
            <TextView
                android:id="@+id/tv_time_value"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/tv_time"
                android:layout_alignBottom="@id/tv_time"
                android:text="@{viewModel.time}"
                tools:text="10:00" />
        </RelativeLayout>
 
        <ProgressBar
            android:id="@+id/pb_progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:visibility="@{viewModel.loading ? View.VISIBLE : View.GONE}" />
 
        <TextView
            android:id="@+id/tv_query_failure"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="@string/query_failure"
            android:visibility="@{viewModel.loadingFailure ? View.VISIBLE : View.GONE}" />
    </RelativeLayout>
</layout>
部分参考自https://www.2cto.com/kf/201805/745059.html 点击打开链接



猜你喜欢

转载自blog.csdn.net/qq_38582588/article/details/80787992