MVVM中的Model
我们可以用任何POJO 作为 data binding 的 Model,
但是直接修改POJO对象,不能直接更新UI
android的 dataBinding 模块 给提供了通知机制,有3中类型的通知机制,分别对应于
类(Observable),
字段(ObservableField),
集合类型(Observable Collections)
dataBinding模块 的机制 ,是 通知 模式
有3中类型的通知机制
类 (Observable)
字段(ObservalbeField)类型
集合(Observable Collections)
把这些observable 对象绑定到 View 后,当 observable 对象更新后UI会自动更新,是因为observable对象绑定到了view
observable 对象 更新后 -->UI会自动更新 ,同时,observable 对象是和view绑定一起的。
======================================================
Observalbe objects 用法
我们需要把 POJO 继承自 BaseObservable ,才能通过 通知UI的能力
private static class User extends BaseObservable{
private String firstName;
private String lastName;
@Bindabel // Bindable标签在编译时会自动生成类 BR,
// 但是Model中的数据发生改变时候,我们在Set方法中调用 notifyPropertyChanged 会通知UI更新。
public String getFirstName(){
return this.firstName;
}
@Bindable
public String getLastName(){
return this.lastName
}
public void setFirstName(String firstName){
this.firsName = firstName;
notifyPropertyChanged(BR.firstName);
}
public void setLastName(String lastName){
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
}
======================================================
ObservableFields用法
创建支持Observable的POJO类,还是有些麻烦
ObservableFields可以简化我们的POJO对象:
private static class User extends BaseObservable{
public final ObservableField<String> firstName = new ObservableField<>();
public final ObservableField<String> lastName = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
可以通过一下方式访问 和 修改字段值
user.firsName.set("Google");
int age = user.age.get();
对应基础数据类型有 ObaservableInt ,ObservableFloat,ObservableBoolean 等可以使用
===============================================================
Observable Collections 用法
DataBinding中提供了一些支持通知机制的集合类型,比如 ObservableArrayList,ObservableArrayMap.
ObservableArrayMap的使用跟Map一样
ObservableArrayMap<String,Object> user= new ObservableArrayMap<>();
user.put("firstName","Google");
user.put("lastName","Inc.");
user.put("age",17);
在Layout中使用ObservableArrayMap中的数据
<data>
<import type="android.databinding.ObservableMap"/>
<variable name ="user" type ="ObservableMap<String ,Object>"/>
</data>
...
<TextView
android:text ="@{user["lastName"]}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:text ='@{String.valueOf(1+(Integer)user["age"])}'
android:layout_width="wrap_content"
android:layout_height ="wrap_content"
/>
==========================================================================
MVVM中的ViewModel
android 中的ViewModel是自动生成的Binding类(继承自android.databinding.ViewDataBinding)
创建Binding对象
我们一般使用Binding对象的静态方法创建Binding对象:
MyLayoutBinding binding = MyLayoutBinding.inflate(laoutInflater);
MyLayoutBinding bingding = MyLayoutBinding.inflate(LayoutInflater,viewGroup,false);
有时候,我们需要使用DataBingdingUtil创建Binding对象
ViewDataBinging binding = DataBindingUtil.inflate(LayoutInflater,layoutId,parent,attachToParent);
ViewDataBinding binding = DataBindingUtil.bindTo(viewRott,layoutId);
设置View的id
使用DataBingding以后,我们一般不需要设置View的id,但是我们有时候也会需要的,设置id后,
ViewDataBinding类会自动生成对应的字段,比如:
<layout xmlns:android ="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User" />
</data>
<LinearLayout
android :orientation ="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text ="@{user.firstName}"
android:id="@id/firstName"
/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
/LinearLayout>
对应的id会自动生成
public final TextView firstName;
public final TextView lastName;
========================================================
Variables
在layout中data区域定义的变量,或自动在Binding类中生成的get/set方法
<data>
<import type="android.graphics.drawable.Drawable" />
<variable name ="user" type="com.example.User" />
<variable name="image" type="Drawable" />
<variable name="note" type="String"/>
</data>
生成的方法如下
public abstract com.example.User getUser();
public abstract Drawable getImage();
public abstract void setImage(Drawable image);
public abstract String getNote();
public abstract void setNote(String note);
=====================================================================
Dynamic Variables
我们无法知道确切的binding类,比如RecyclerView Adapter可以使用任意的layout.
所以我们的binding类需要动态生成。
我们需要在onBindViewHolder方法中给变量赋值,比如我们的layout中声明了一个item变量,
我们通过BindingHolder的getBinding返回一个binding对象,调用setVariable方法给item变量赋值
public void onBindViewHolder(BindingHolder holder,int position){
final T item = mItems.get(position);
holder.getBinding().setVariable(BR.item,item);
holder.getBinding().executePendingBindings();
}
binding 对象需要在onCreateViewHolder中创建
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),R.layout.list_item,viewGroup,flase);
BindingHolder holder = new BindingHolder(binding.getRoot());
holder.setBinding(binding);
Holder: 持有人
inflate ;膨胀
Observable:可观察量