MVVM的使用和原理
来源:互联网 发布:阿里云cdn公共库 编辑:程序博客网 时间:2024/06/06 12:55
一、MVC、MVP、MVVM的区别。
Android以往的架构都类似于MVC,在MVC中视图层是非常弱化的,造成C层代码量非常大。所以MVC架构模式可以理解成M-VC,是一个二层架构。几乎所有的视图逻辑都要写在Activity中,一个Activity可能有上千行。MVP改善了MVC的这种问题,将视图层抽象成一个IView接口,将业务逻辑和数据处理丢给Presenter,Presenter持有Iview的引用,解决了MVC中Activity代码过于臃肿的问题。而这也造成了一个问题,当业务过多时,IView的数量也会增多。如果一个Presenter只操作一个IView则违反了单一原则,粒度太大,解耦效果不好;如果将不同的功能区分成不同的IView接口,粒度太小。代码则太过碎片化。而且数据变化之后UI不会自动变化,数据不会直接映视到UI中。MVVM解决了上述的缺点,MVVM最大的亮点就是数据和View的双向绑定,MVVM通过DataBinding将View和Model进行绑定,当Model发生改变时VIew也会改变,不需要在Activity中再添加代码。
二、MVVM的使用。
1、在build.gradle中添加DataBinding,DataBinding是实现MVVM的一个工具,Android studio中已经集成,添加起来非常方便。
dataBinding{ enabled true }
Data Binding 插件需要Gradle 1.3以上及Android Studio 1.3.
2、引入DataBinding之后,layout的写法会发生些改变。要以layout标签作为根节点。通过data标签来绑定model。写法如下
<layout xmlns:android="http://schemas.android.com/apk/res/android" > <data> <!--此处定义该布局要用到的数据的名称及类型--> </data> <!--此处按照常规方式定义要使用的布局,其中可以使用binding表达式代表属性值,所谓binding表达式,指形如"@{user.firstName}"的表达式--></layout>
在对应的VIew中添加Model,写法是@{内容},比如@{user.name},除此之外DataBinding还支持其他运算符如字符串拼接(@{`名字`:·+user.name}),数学表达式(+-/%等),三元操作符android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"支持dimen,还支持color、string、drawable、anim等
3、在设置视图的时候,不能再通过setContentView来设置视图,要通过DataBindingUtil.setContentView来设置视图,在设置DataBindingUtil.setContentView时会返回一个Binding对象,这个Binding对象的命名原则是布局名称(首字母大写)+Binding,例如我的布局名称叫做activity_main,我的Binding对象就叫做ActivityMainBinding。ActivityMainBinding binding=DataBindingUtil.setContentView(this,R.layout.activity_main)这个Binding类所在包为apppackage/databinding中。
然后通过这个BInding来设置数据
binding.setUser(user);
4、加载自定义属性。当我们加载图片时,需要添加自定义的属性。自定义属性需要在实体中写好。
@BindingAdapter("bind:header") public static void getImage(ImageView view,String url) { Picasso.with(view.getContext()).load(url).into(view); }这个方法一定要是静态的。
然后在layout中调用。
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:header="@{user.header}" />5、当modle发生改变时,改变VIew。两种写法,第一个直接让实体类继承BaseObservable,第二种写法是将实体抽离出来单独放入一个类。
public class UserField { public ObservableField<String> name=new ObservableField<>(); public ObservableField<String> password=new ObservableField<>();}
然后在布局中引入UserField。
<variable name="field" type="com.example.administrator.mvvmframwork.UserField"/>在layout应用model中用field代替user
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@{` `+field.name}" />别忘了在Activity中添加
binding.setField(userField);无论哪种写法,都需要在对应的属性的set方法上添加@Bindable
@Bindable public String getPassword() { return password; }
6、listVIew和DataBinding
listview或者RecyclerView和DataBinding搭配使用时很方便,因为adapter只需要写一个就好了。
我们利用item和model绑定,绑定过程和上面差不多,主要是adapter 的写法有了些变化
public class ComonAdapter<T> extends BaseAdapter { private Context context; private LayoutInflater inflater; private int layoutId; private int variableId; //List <Food> User private List<T> list; public ComonAdapter(Context context, LayoutInflater inflater, int layoutId, int variableId, List<T> list) { this.context = context; this.inflater = inflater; this.layoutId = layoutId; this.variableId = variableId; this.list = list; } @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) { ViewDataBinding dataBinding; if(convertView==null) { dataBinding= DataBindingUtil.inflate(inflater,layoutId,parent,false); }else { //重用DataBinding dataBinding=DataBindingUtil.getBinding(convertView); } dataBinding.setVariable(variableId,list.get(position)); //返回item视图 return dataBinding.getRoot().getRootView(); }}
variableId是一个Model,是数据和View绑定的类型,和上面的DataBinding一样是在编译时生成的。我上面使用的variableID是BR.food。点进去它的内容很像我们的R文件。
public class BR { public static final int _all = 0; public static final int field = 1; public static final int food = 2; public static final int name = 3; public static final int password = 4; public static final int user = 5;}
7、添加点击事件。我们直接去model里面去写
public void click(View view) { Toast.makeText(view.getContext(),getDescription(),Toast.LENGTH_SHORT).show(); }在layout中去调用
<TextView android:id="@+id/description" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_toRightOf="@id/iv" android:ellipsize="end" android:maxLines="3" android:onClick="@{food.click}" android:text="@{food.description}"/>
三、原理。
采用了MVVM之后,编译之后的class类会很多。每个layout中的一个data标签都会单独生成一个Binding。一个activity_main.xml文件编译后会生成一个activity_main.xml和一个activity_main-layout.xml,在activity_main中去掉了<layout>标签,<layout>这部分内容单独编译进activity_main-layout.xml中
未完待续...
阅读全文
1 0
- MVVM的使用和原理
- MVVM 的使用
- MVVM的简单使用
- MVVM的简单使用
- MVVM模式的使用
- MVVM下RadioButton单选钮和ComboBox下拉框的使用
- 高效开发 MVVM 和 databinding 你需要使用的工具
- 谈谈MVVM中DelegateCommand:ICommand的原理
- MVVM Light Messenger的使用
- MVVM的简单使用流程
- mvvm command的使用案例
- ASP.NET MVC框架下使用MVVM模式 knockoutjs的实现原理
- MVVM的优点和缺点
- mvc和mvvm的区别
- MVC和MVVM的区别和联系
- 前端的MVC和MVP和MVVM
- MVC和MVP和MVVM的区别
- 说说Android的MVP模式,mvc以及mvvm它们的区别和使用的原则
- Spring Boot学习之旅:(六)springboot 整合 redis 以及 redis 通用工具类
- 欢迎访问我的个人网站
- React性能优化总结
- 例题6-6 UVA679
- Chrome 开发者控制台中,你可能意想不到的功能
- MVVM的使用和原理
- Web真相: CSS不是真正的编程
- React性能优化——工具篇
- 关于保研的总结和近期的展望
- 数据结构一
- Leetcode540. 二分查找找出数组中只出现一次的元素
- 【bzoj2809】【APIO2010】派遣
- React性能优化——代码篇
- 搭配衣服(基于上一版的改进)