一. 什么是单向绑定?
DataBinding的本身是对View层状态的一种观察者模式的实现,通过让View与ViewModel层可观察的对象进行绑定,当ViewModel层数据发生变化,View层也会自动进行UI的更新。
二. 单项绑定是用来干嘛的?
前面我们讲了DataBinding的作用就是实现数据绑定,但我们上面写的代码绑定的控件的内容,没有随着绑定变量的值发生改变的时候,因此每次都得重新向ViewDataBinding传值然后跟新UI,那我们能不能让DataBinding自己自动去刷新UI?其实单向绑定就可以实现这个效果!!
使用单向绑定刷新UI有三种
- 使用 BaseObservable (比较麻烦)
- 使用 ObservableField
- 使用 ObservableCollection
三. 使用BaseObservable实现单向绑定
1. BaseObservable方法介绍
notifyChange(); 会刷新所有UI。
notifyPropertyChanged(); 只会刷新属于它的UI,需要绑定属性。
2. Bean类写法
package com.qy.databinddemo;
public class UserBean {
@Bindable//这里要进行绑定,否则会编译报错
private String name;
private String csdnAddress;
public UserBean(String name, String csdnAddress) {
this.name = name;
this.csdnAddress = csdnAddress;
}
public void setName(String name) {
this.name = name;
//这个方法只会刷新属于它的UI
notifyPropertyChanged(BR.name);
}
public void setName2(String name) {
this.name = name;
}
public void setCsdnAddress(String csdnAddress) {
this.csdnAddress = csdnAddress;
//这个方法会刷新所有UI
notifyChange();
}
public String getName() {
return name;
}
public String getCsdnAddress() {
return csdnAddress;
}
@Override
public String toString() {
return "UserBean{" +
"name='" + name + '\'' +
",csdnAddress='" + csdnAddress + '}';
}
}
3. MainActivity中的写法
public class MainActivity extends AppCompatActivity{
private ActivityMainBinding binding;
private UserBean user;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
binding = DataBindingUtil
.setContentView(this,R.layout.activity_main);
user = new UserBean
("苏青岩","https://blog.csdn.net/qq_35953420");
//绑定数据
binding.setData(user);
//绑定事件
binding.setListener(new ButtonListener());
}
public class ButtonListener{
public void changeName(){
user.setName("改变的名字");
Toast.makeText(MainActivity.this,
"改变Name",Toast.LENGTH_SHORT).show();
}
public void changeAddress(){
user.setName2("百度");
user.setCsdnAddress("www.baidu.com");
Toast.makeText(MainActivity.this,
"改变所有UI",Toast.LENGTH_SHORT).show();
}
}
}
4. 布局写法
<?xmlversion="1.0"encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import
type="com.qy.databinddemo.UserBean"/>
<variable
name="data"
type="UserBean"/>
<!--事件监听-->
<import
type="com.qy.databinddemo.MainActivity.ButtonListener"/>
<variable
name="listener"
type="ButtonListener"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:text="@{data.name,default=默认值}"/>
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:text="@{data.csdnAddress}"/>
<!--事件监听控件-->
<Button
android:id="@+id/buttonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改名字"
android:onClick="@{()->listener.changeName()}"/>
<Button
android:id="@+id/buttonAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="修改地址"
android:onClick="@{()->listener.changeAge()}"/>
</LinearLayout>
</layout>
四. 使用ObservableField实现单向绑定
1. Bean类写法
public class UserBean extends BaseObservable{
public final ObservableField<String> name;
public final ObservableField<String> address;
public UserBean(ObservableField<String> name,
ObservableField<String> address){
this.name=name;
this.address=address;
}
public ObservableField<String> getName(){
return name;
}
public ObservableField<String> getAddress(){
return address;
}
}
2. MainActivity中的写法
public class MainActivity extends AppCompatActivity{
private ActivityMainBinding binding;
private UserBean user;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView
(this,R.layout.activity_main);
user = new UserBean
(new ObservableField<String>("苏青岩"),
new ObservableField<String>("CSDN苏青岩"));
//绑定数据
binding.setData(user);
//绑定事件
binding.setListener(new ButtonListener());
}
public class ButtonListener{
public void changeName(){
user.setName("改变的名字");
Toast.makeText(MainActivity.this,
"改变Name",Toast.LENGTH_SHORT).show();
}
public void changeAddress(){
user.setName2("百度");
user.setCsdnAddress("www.baidu.com");
Toast.makeText(MainActivity.this,
"改变所有UI",Toast.LENGTH_SHORT).show();
}
}
}
五. 使用 ObservableCollection实现单向绑定(ObservableMap)
1. 布局写法(ObservableMap)
<?xmlversion="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">
<data>
<import type="androidx.databinding.ObservableMap"/>
<variable
name="user"
type="ObservableMap<String,Object>"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/user1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user["one"]}'/>
<TextView
android:id="@+id/user2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user["two"]}'/>
<TextView
android:id="@+id/user3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user["three"]}'/>
<TextView
android:id="@+id/user4"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user["four"]}'/>
</LinearLayout>
</layout>
2. MainActivity中的写法(ObservableMap)
public class MainActivity extends AppCompatActivity{
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView
(this,R.layout.activity_main);
ObservableMap<String,Object> user =
new ObservableArrayMap< >();
user.put("one","苏青岩是帅哥1");
user.put("two","苏青岩是帅哥2");
user.put("three","苏青岩是帅哥3");
user.put("four","重要的事情说三遍");
binding.setUser(user);
}
}
3. 效果
六. 使用 ObservableCollection实现单向绑定(ObservableList)
1. 布局写法(ObservableList)
<?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">
<data>
<import
type="androidx.databinding.ObservableList"/>
<variable
name="user"
type="ObservableList<String>"/>
<import
type="com.qy.databindingdemo.MainActivity.ChangeTextView"/>
<variable
name="changetext"
type="ChangeTextView"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/user1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user[0]}'/>
<TextView
android:id="@+id/user2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user[1]}'/>
<TextView
android:id="@+id/user3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user[2]}'/>
<TextView
android:id="@+id/user4"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text='@{user[3]}'/>
<Button
android:id="@+id/buttonOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{()->changetext.changeText()}"
android:text='谁最帅??'/>
</LinearLayout>
</layout>
2. MainActivity中的写法(ObservableList)
public class MainActivity extends AppCompatActivity{
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
binding =DataBindingUtil.setContentView
(this,R.layout.activity_main);
user = new ObservableArrayList<>();
user.add("苏青岩是帅哥1");
user.add("苏青岩是帅哥2");
user.add("苏青岩是帅哥3");
user.add("重要的事情说三遍");
binding.setUser(user);
binding.setChangetext(new ChangeTextView());
}
public class ChangeTextView{
public void changeText(){
for(int i=0,size=user.size();i<size;i++){
user.set(i,"苏青岩"+i);
}
}
}
}
3. 效果