MVVM中data binding系列(三)

动态更新和双向绑定
根据Model实体类的内容来动态更新UI,分别对应字段(ObservableField),类(Observable),集合类型(Observable 容器类)

1.使用Observable

首先我们需要定义Model实体类

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import com.mvvm.BR;
public class Student extends BaseObservable {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);
    }

    @Bindable
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        notifyPropertyChanged(BR.age);
    }
}

实体类注意三点

  • 需要继承BaseObservable 类
  • get方法添加@Bindable注解
  • set方法添加notifyPropertyChanged(BR.age)告诉dataBind该数据的哪个属性变了

然后在Activity中使用

 @Override
  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CustomBinding dataBind = DataBindingUtil.setContentView(this, R.layout.activity_main);
        Student std = new Student("Tom",22);
        dataBind.setStudent(std);
        dataBind.tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG,"name 的点击事件");
                std.setName("小强");
            }
        });
 }

这里只要一点击页面上的"Tom"就会自动变为"小强"。

2.使用ObservableField

我们也先自定义Model实体类

import androidx.databinding.ObservableField;
public class Student  {
    public ObservableField<String> name = new ObservableField<>();
    public ObservableField<Integer> age = new ObservableField<Integer>();

    public Student(String name, int age) {
        this.name.set(name);
        this.age.set(age);
    }

    public ObservableField<String> getName() {
        return name;
    }

    public void setName(ObservableField<String> name) {
        this.name = name;
    }

    public ObservableField<Integer> getAge() {
        return age;
    }

    public void setAge(ObservableField<Integer> age) {
        this.age = age;
    }
}

这里需要关注两点

  • 变量的申明用ObservableField<T>接收。
  • 构造函数传进来的属性值要通过ObservableField的set方法设置进去。

在看看Activity中的代码

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CustomBinding dataBind = DataBindingUtil.setContentView(this, R.layout.activity_main);
        Student std = new Student("Tom",22);
        dataBind.setStudent(std);
        dataBind.tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG,"name 的点击事件");
                std.name.set("小强");
            }
        });
    }

通过这种方式,直接设置std.name.set(“小强”),也可以改界面显示。

3.使用Observable容器类

使用Observable容器类可以同时刷新多个对象。容器类有ObservableArrayList 和ObservableArrayMap。这里举例使用ObservableArrayList 。
对于Model类的使用几乎没有要求,按非data Binding的模式写也可以。

public class Teacher {
   public String name;
   public int age;


    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

再看看布局文件的使用

 <import type="com.mvvm.model.Teacher"/>
 <import type="androidx.databinding.ObservableArrayList"/>

 <variable
            name="list"
            type="ObservableArrayList&lt;Teacher>" />
    <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list[0].name}" />

      
    <TextView
            android:id="@+id/tv_name1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list[1].name}" />

这里三个注意点

  • 布局文件首先要导集合和元素的类的包
  • 注意泛型的写法
  • 注意集合的访问方式
4.双向绑定

双向绑定就是Model层数据发生了变化,UI层应该动态更新。UI层的显示发生了变化,Model数据层也应该随之改变。
双向绑定用法比较简单,只需要将android:text="@{teacher.name}“改成android:text=”@={teacher.name}"即可。
接下来我们用EditText试用一下

布局文件

 <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:text="@={teacher.name}"/>

注意导包和变量的申明
Activity中的用法

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CustomBinding dataBind = DataBindingUtil.setContentView(this, R.layout.activity_main);
        Teacher teacher = new Teacher("李白",18);
        dataBind.setTeacher(teacher);
		 dataBind.et.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) {
                String string = s.toString();
                Log.d(TAG,"输入框数据是 :"+string);
                Log.d(TAG,"teacher.name :"+teacher.getName());
            }
        });
    }
}

看看打印结果:

2020-11-22 14:45:33.614 22908-22908/com.mvvm D/MainActivity: 输入框数据是 :李白
2020-11-22 14:45:33.614 22908-22908/com.mvvm D/MainActivity: teacher.name :李白
2020-11-22 14:45:38.372 22908-22908/com.mvvm D/MainActivity: 输入框数据是 :李
2020-11-22 14:45:38.372 22908-22908/com.mvvm D/MainActivity: teacher.name :李
2020-11-22 14:45:45.318 22908-22908/com.mvvm D/MainActivity: 输入框数据是 :
2020-11-22 14:45:45.318 22908-22908/com.mvvm D/MainActivity: teacher.name :
2020-11-22 14:45:47.833 22908-22908/com.mvvm D/MainActivity: 输入框数据是 :d
2020-11-22 14:45:47.833 22908-22908/com.mvvm D/MainActivity: teacher.name :d
2020-11-22 14:45:48.052 22908-22908/com.mvvm D/MainActivity: 输入框数据是 :du
2020-11-22 14:45:48.052 22908-22908/com.mvvm D/MainActivity: teacher.name :du
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值