创建数据模型类
package com.wzp.bindwzp.model;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import com.wzp.bindwzp.BR;
//继承BaseObservable
public class Information extends BaseObservable {
//因为属性使用的是 public修饰所以可以直接在这里使用注解@Bindable
@Bindable
public String phone;
public Information(String phone) {
this.phone = phone;
}
//如果不是public 则在这里使用@Bindable
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
//防止循环调用
if(phone.equals(this.phone)){
return;
}
this.phone = phone;
//数据有更新了通知 view视图重新从@Bindable修饰的属性里取值
notifyPropertyChanged(BR.phone);
}
}
创建自定义属性
package com.wzp.bindwzp;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import androidx.databinding.BindingAdapter;
import androidx.databinding.InverseBindingAdapter;
import androidx.databinding.InverseBindingListener;
public class SelfAttr {
//数据流向视图
@BindingAdapter(value ={"myText"},requireAll = false)
public static void setAttrMyText(EditText view,String text){
//在xml里 myText="@={per.phone}"对应的per.phone数据变化的时候自动调用这个方法
//在xml里设置了android:text="@{per.phone}" 所以这里可以不用这样写view.setText(text);
}
//myText="@={per.phone}" xml里填写这个属性的时候会自动调用一次这个方法,myText + AttrChanged ,AttrChanged是固定写法
@BindingAdapter(value = {"myTextAttrChanged"},requireAll = false)
public static void setAttrMyTextListener(EditText view, InverseBindingListener listener){
if(listener != null){
view.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
listener.onChange();
//view视图层有变化
}
});
}
}
//视图流向数据模型
//响应上面myTextAttrChanged里的listener.onChange(),反向设置数据的时候从这里取值;
@InverseBindingAdapter(attribute = "myText",event = "myTextAttrChanged")
public static String getMyText(EditText view){
return view.getText().toString();
}
}
创建layout布局
<?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"
tools:context=".Mvvm2Activity">
<!--layout里不能写其他属性比如 android:layout_width -->
<!--mvvm固定写法 layout最外层, data里引用数据模型-->
<!--data-->
<data>
<import type="com.wzp.bindwzp.model.Information"/>
<!--name="per" 自己随便写表示变量的别名-->
<variable
name="per"
type="com.wzp.bindwzp.model.Information" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/iv_phone"
android:text="@{per.phone}"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!--因为EditText里有setText方法所以也可用这样:
android:text="@={per.phone}" 实现双向绑定
这里的myText是为了演示无setText方法或者需要在双向绑定里添加自己的逻辑
-->
<EditText
android:text="@{per.phone}"
myText="@={per.phone}"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</layout>
最后在activity里绑定
public class Mvvm2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMvvm2Binding binding = DataBindingUtil.setContentView(this, R.layout.activity_mvvm2);
binding.setPer(new Information("测试"));//给xml里的per变量赋值
}
}