我们一步步来,从MVC开始。
MVC 我们都知道,模型——视图——控制器。为了使得程序的各个部分分离降低耦合性,我们对代码的结构进行了划分。
他们的通信方式也如上图所示,即View层触发操作通知到业务层完成逻辑处理,业务层完成业务逻辑之后通知Model层更新数据,数据更新完之后通知View层展现。在实际运用中人们发现View和Model之间的依赖还是太强,希望他们可以绝对独立的存在,慢慢的就演化出了MVP。
Presenter 替换掉了Controller,不仅仅处理逻辑部分。而且还控制着View的刷新,监听Model层的数据变化。这样隔离掉View和Model的关系后使得View层变的非常的薄,没有任何的逻辑部分又不用主动监听数据,被称之为“被动视图”。
至于MVVM基本上和MVP一模一样,感觉只是名字替换了一下。他的关键技术就是今天的主题(Data Binding)。View的变化可以自动的反应在ViewModel,ViewModel的数据变化也会自动反应到View上。这样开发者就不用处理接收事件和View更新的工作,框架已经帮你做好了。
Data Binding Library
今年的Google IO 大会上,Android 团队发布了一个数据绑定框架(Data Binding Library)。以后可以直接在 layout 布局 xml 文件中绑定数据了,无需再 findViewById 然后手工设置数据了。其语法和使用方式和 JSP 中的 EL 表达式非常类似。
下面就来介绍怎么使用Data Binding Library。
以上是应用网上的一些资料,就是简单介绍下
接下来上代码
首先配置环境,在gradle中
android{
dataBinding{ enabled = true }
}
dataBinding的布局文件和我平时写的有些不同,他的根节点是layout
来让我们看一下
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <import type="android.text.TextUtils" /> <variable name="myEvent" type="com.example.wudz.mvvm.MVVMActivity.MyEvent" /> <variable name="user" type="com.example.wudz.bean.UserBean" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="@{TextUtils.isEmpty(user.name)?null: user.name}" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="年龄:" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="@{TextUtils.isEmpty(user.age)?null: user.age}" /> </RelativeLayout> <Button style="@style/btn" android:onClick="@{myEvent.setInf}" android:text="设置name和age" /> <ListView android:id="@+id/lv_user" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView> </LinearLayout> </layout>
里面包含data节点,data里面包含import节点和variable节点,其中variable节点中的name相当于我们在类里面的变量名(个人理解的),type相当于类型,只不过是全路径的,这点要注意,当然,如果是string、int等,就不用写完整路径了
android:text="@{user.name}是吧UserBean的name属性和TextView 的text属性绑定起来,
在布局里面可以使用多种表达式:
-
数学表达式 + – / * %
-
字符串链接 +
-
逻辑操作符 && ||
-
二元操作符 & | ^
-
一元操作符 + – ! ~
-
Shift >> >>> <<
-
比较 == > < >= <=
-
instanceof
-
Grouping ()
-
Literals – character, String, numeric, null
-
Cast
-
函数调用
-
值域引用(Field access)
-
通过[]访问数组里面的对象
-
三元操作符 ?:
示例:android:text="@{String.valueOf(index + 1)}" android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}" android:transitionName='@{"image_" + id}'
可以参考:http://developer.android.com/tools/data-binding/guide.html#expression_language
看下userBean
package com.example.wudz.bean; import android.databinding.BaseObservable; import android.databinding.Bindable; import java.io.Serializable; /** * USER:wudz on 2016/11/2 09:57 * <p> * EMAIL:wudz@qianbaocard.com * <p> * TODO */ public class UserBean extends BaseObservable implements Serializable { private String name; private String age; public void setName(String name) { this.name = name; } @Bindable public String getName() { return name; } @Bindable public String getAge() { return age; } public void setAge(String age) { this.age = age; } }
让你的绑定数据类继承BaseObservable,然后通过调用notifyPropertyChanged方法来通知界面属性改变
在需要通知的属性的get方法上加上@Bindable,这样编译阶段会生成BR.[property name],然后使用这个调用方法notifyPropertyChanged就可以通知界面刷新了。如果你的数据绑定类不能继承BaseObservable,那你就只能自己实现Observable接口,可以参考BaseObservable的实现。
还可以这样做,我没写到demo中,在网上找的一段,大家参考下
方案二
Data Binding Library提供了很便利的类ObservableField,还有ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, 和 ObservableParcelable,基本上涵盖了各种我们需要的类型。用法很简单,如下:
private static class User {
public final ObservableField<String> firstName = new ObservableField<>();
public final ObservableField<String> lastName = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
然后使用下面的代码来访问:
user.firstName.set("Google");int age = user.age.get();
调用set方法时,Data Binding Library就会自动的帮我们通知界面刷新了。
在java代码中调用
package com.example.wudz.mvvm; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import com.example.wudz.bean.UserBean; import com.example.wudz.mvvm.databinding.ActivityMvvmBinding; import com.example.wudz.mvvm.databinding.ItemUserBinding; import java.util.ArrayList; import java.util.List; /** * USER:wudz on 2016/11/2 09:54 * <p> * EMAIL:wudz@qianbaocard.com * <p> * TODO */ public class MVVMActivity extends AppCompatActivity { //在这里会生成ViewDataBinding的形势的类,继承ViewDataBinding private ActivityMvvmBinding binding; private ListView lvUser; private List<UserBean> list = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this,R.layout.activity_mvvm); binding.setMyEvent(new MyEvent()); lvUser = (ListView) binding.getRoot().findViewById(R.id.lv_user); UserBean user = new UserBean(); user.setAge("20"); user.setName("小明"); list.add(user); list.add(user); list.add(user); list.add(user); list.add(user); list.add(user); list.add(user); list.add(user); lvUser.setAdapter(new MyAdapter()); } public class MyEvent{ public void setInf(View view){ UserBean user = new UserBean(); user.setAge("20"); user.setName("小明"); binding.setUser(user); } } class MyAdapter extends BaseAdapter{ ItemUserBinding itemUserBinding; @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null){ itemUserBinding = DataBindingUtil.inflate(LayoutInflater.from(MVVMActivity.this),R.layout.item_user,parent,false); convertView = itemUserBinding.getRoot(); convertView.setTag(itemUserBinding); }else{ itemUserBinding = (ItemUserBinding) convertView.getTag(); } itemUserBinding.setUser(list.get(position)); return convertView; } } }
另外就是在adapter适配器中稍微有点不一样,
以前我们都是定义一个viewHolder什么的,在这里我们获取到itemUserBinding,把这个对象设置converView的tag中,这里类似viewholder了,在给item设置值得时候,直接itemUserBinding.setUser(list.get(position))
现在大多人都用RecycleView,这里只是给大家举个例子,
以上就是MVVM的简单介绍,欢迎补充
附上demo地址
https://github.com/wudongze/MVVM
相关推荐
**MvvmLight 简介** MvvmLight(Model-View-ViewModel Light)是由法国开发者Laurent Bugnion创建的一个轻量级MVVM(Model-View-ViewModel)框架,适用于WPF、Silverlight、Windows Phone、Universal Windows ...
**MVVM模式简介** MVVM模式的核心思想是通过数据绑定机制,使得View和ViewModel之间可以自动同步数据变化,而无需直接操作UI元素。ViewModel作为View和Model之间的桥梁,负责处理业务逻辑和数据处理,而View则负责...
**C# MVVM架构简介** MVVM(Model-View-ViewModel)是一种软件设计模式,尤其在开发WPF、UWP和Xamarin等基于.NET Framework的桌面应用或移动应用时广泛应用。该模式源自经典的MVC(Model-View-Controller)模式,但...
**MVVM模式简介** MVVM模式由三个主要部分组成:模型(Model)、视图(View)和视图模型(ViewModel)。模型负责数据处理和业务逻辑,视图负责用户界面的展示,而视图模型作为桥梁,连接模型和视图,处理数据转换和...
MVVM模式简介 MVVM模式由三个主要组件构成: - **Model(模型)**:负责业务逻辑和数据处理,通常与数据库或其他数据源交互。 - **View(视图)**:用户界面部分,用于展示数据和接收用户输入。 - **ViewModel...
1. MVVM模式简介 MVVM模式的核心思想是解耦视图和业务逻辑,通过数据绑定将View与ViewModel连接,ViewModel再与Model交互。这样,开发者可以在不修改视图的情况下修改业务逻辑,反之亦然。ViewModel提供了数据和行为...
基于Qt+opencv+MVVM实现的视频播放器源码,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心...项目使用了MVVM软件架构来进行开发。 实现了一个视频播放器,支持播放部分格式的媒体文件,例如MP4
**MVVM模式简介** MVVM(Model-View-ViewModel)是一种软件设计模式,广泛应用于现代UI开发,尤其是在WPF、UWP、Android以及Angular、React等前端框架中。该模式将应用程序分为三个主要部分:模型(Model)、视图...
**MVVM架构简介** MVVM由Microsoft在WPF框架中首次引入,随后被广泛应用于各种平台,包括Android。这个模式主要包含三个组件: 1. **Model(模型)**:代表应用程序的数据和业务逻辑,负责处理数据的获取和存储。它...
**MVVM模式简介** MVVM(Model-View-ViewModel)是一种软件设计模式,广泛应用于现代UI开发,尤其是在WPF、UWP、Android、iOS以及Web前端等平台。它源自MVC(Model-View-Controller)模式,但针对UI开发做了优化,...
**MVVM模式简介** MVVM模式由三个主要部分组成: 1. **Model(模型)**:代表应用的数据模型或业务实体,通常与数据库或其他数据源交互。 2. **View(视图)**:负责显示UI,用户与之交互。在WPF中,View通常是XAML...
**MVVM简介** MVVM由微软的WPF团队提出,主要目的是为了简化用户界面(UI)的设计和开发,通过分离关注点,让开发者能够专注于业务逻辑和数据模型,而设计师则可以独立地处理视图。该模式由三个主要组件组成:Model...
MVVM架构简介 MVVM是由三个主要组件组成的:Model(模型)、View(视图)和ViewModel(视图模型)。这个模式的主要目标是分离业务逻辑和用户界面,使得开发者可以专注于各自领域的开发,从而提高效率。 - **Model...
**MVVM模式简介** MVVM模式由三个主要部分组成:模型(Model)、视图(View)和视图模型(ViewModel)。模型负责数据处理和业务逻辑,视图负责用户界面的展示,而视图模型作为桥梁,连接模型和视图,处理它们之间的...
在创建一个基于MVVM的Windows Store应用时,我们通常会使用C++/CX,这是一种扩展了C++的编程语言,专为Windows Runtime设计。XAML则用于定义UI布局和控件,它支持数据绑定和事件处理,是MVVM模式的重要组成部分。 ...
在本文中,我们将深入探讨如何使用WPF(Windows Presentation Foundation)与MvvmLight库构建一个简单的导航实例。WPF是Microsoft推出的一种强大的UI框架,它提供了丰富的图形效果和灵活的布局管理,而MvvmLight...
这个名为"ios-mvvm架构简单实用.zip"的压缩包文件,显然是一个关于如何使用MVVM模式来实现一个电影列表页面的示例项目,名为"mvvmDemo"。 MVVM架构的核心概念是将视图(View)、模型(Model)和视图模型(ViewModel...
在本文中,我们将深入探讨如何使用MVVM(Model-View-ViewModel)设计模式来构建一个基于WPF(Windows Presentation Foundation)的应用程序。这个示例着重于通过操作XML数据来实现基本的CRUD(创建、读取、更新、...
在本文中,我们将深入探讨如何使用MVVM(Model-View-ViewModel)模式和依赖属性来实现WPF(Windows Presentation Foundation)中的TreeView控件的多选功能。MVVM是一种设计模式,它鼓励分离关注点,使应用程序更易于...
**一、MVVM模式简介** 1. **模型(Model)**:模型是业务逻辑和数据的封装,通常包含业务对象和数据访问组件。在WPF中,模型并不直接与视图交互,而是通过视图模型进行通信。 2. **视图(View)**:视图是用户看到和...