MVVM之DataBinding的使用

DataBinding在MVVM框架中的作用:为数据与xml文件实现了双向绑定。即数据的变化可以自动刷新界面,View在一些操作上也会自动的更新数据。减少了Activity的工作量。

1.使用DataBinding

在build.gradle中添加

dataBinding {
        enabled = true
    }

然后在xml文件的根标签上ALT + 回车键 然后选择Convert to data binding layout

MVVM之DataBinding的使用_第1张图片

最后变成:




    

    

    

    

根标签为layout,data标签里面就是我们要绑定的数据声明。

 

2.DataBinding的基本使用

我们先声明一个类:

public class Person {
    public String name;
    public String address;

    public Person(String name, String address) {
        this.name = name;
        this.address = address;
    }
}

在xml文件中也声明这个类

 
        
    

type指的是Person的全路径,name为Person的变量名。也可以使用import标签声明:


        
        
    

import标签中也可以使用 alias 属性 声明别名。

使用变量:



        

        

    

可以看到通过 @{变量名.属性}方式来引用。可以通过default来让xml显示默认值

 

        

在Activity中绑定数据:

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        binding.setPerson(new Person("小王","南方"));
    }

编译器会自动生成ActivityDataBinding类。如果你的xml文件名字为activity_main 就会生成ActivityMainBinding类。

3.DataBinding的事件绑定

方式一:

方式二:

 


 

 

4.单向数据绑定

在绑定数据后,我们希望能做到数据变化后,UI也可以随着变化。DataBinding提供了三种方式:

BaseObservable,ObservableField,ObservableCollection

(1)BaseObservable

BaseObservable提供了notifyChange() 和 notifyPropertyChanged()两个方法。前者会刷新所有的值;后者则只更新有注解@Bindable的值。

public class Person extends BaseObservable {
    private String name;
    private String address;
    private String info;

    public Person(String name, String address, String info) {
        this.name = name;
        this.address = address;
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

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

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

    @Bindable
    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setNotifyChangeAll(){  //更新全部属性值
        notifyChange();
    }

    public void setNotifyChangeSingle(){  //只更新address属性值
        notifyPropertyChanged(BR.address);
    }

}
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setPerson(person = new Person("小王", "南方", "舒服"));//绑定数据
        binding.setEvent(this);//绑定事件
    }

    private Person person;

    public void changeAll() {  //更新属性值
        person.setInfo("天气晴朗" + SystemClock.currentThreadTimeMillis());
        person.setAddress("深圳" + SystemClock.currentThreadTimeMillis());
        person.setName("小红" + SystemClock.currentThreadTimeMillis());
        person.setNotifyChangeAll(); //调用全部更新方法
    }

    public void changeSingle() { // 更新属性值
        person.setInfo("天气多云转阴" + SystemClock.currentThreadTimeMillis());
        person.setAddress("广州" + SystemClock.currentThreadTimeMillis());
        person.setName("小白" + SystemClock.currentThreadTimeMillis());
        person.setNotifyChangeSingle(); //调用单个更新方法


    }

}

(2)ObservableField

ObservableField 是对BaseObservable的封装,再也不需要手动的调用notifyChahange()和notifyPropertyChanged()了。

public class Person extends BaseObservable {
    public  ObservableField name = new ObservableField<>();
    public  ObservableField address = new ObservableField<>();
    public  ObservableField info = new ObservableField<>();
}
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        person = new Person();
        person.name.set("小王");
        person.address.set("南方");
        person.info.set("阴雨绵绵");
        binding.setPerson(person);
        binding.setEvent(this);
    }

    private Person person;

    public void changeAll() {
        person.name.set("小芳" + SystemClock.currentThreadTimeMillis());
        person.address.set("深圳" + SystemClock.currentThreadTimeMillis());
        person.info.set("万里长空" + SystemClock.currentThreadTimeMillis());
    }

    public void changeSingle(){

    }

}

(3)ObservableCollection

DataBinding提供了包装类用于替代原生的List和Map,分别是ObservableList 和 ObservableMap。

当其包含的数据发生变化时,绑定的视图也会随之进行刷新。

private ObservableArrayList listInfo; //创建ObservableArrayList
private ObservableArrayMap mapInfo; //创建ObservableArrayMap


 listInfo = new ObservableArrayList<>();
        listInfo.add("A");
        listInfo.add("B");

        mapInfo = new ObservableArrayMap<>();
        mapInfo.put("a","苹果");
        mapInfo.put("b","橘子");
        binding.setKey("a");
        binding.setLists(listInfo);//绑定数据
        binding.setMaps(mapInfo);  //绑定数据

在xml中引用:





 
 

需要注意的是:不要使用<>, 而是使用< 和 >代替它们。

 

        


数据变化时UI会自动更新
listInfo.set(0, "AA");
mapInfo.put("a","苹果苹果");


5.双向绑定

我们不只是希望能做到数据驱动UI的变化,同时我们也希望UI变化时,相应的数据有跟着变化。

 

注意:是 @={}

打印:tag: 阴雨绵绵bianchengwanliwuyunle

 

6.BindingAdapter 

Databinding支持自定义属性。

public class Utils {
    @BindingAdapter({"imageUrl"})
    public static void setImageUrl(ImageView imageView, String url){
        Log.e("tag",url);
    }
}

xml中:

 


注意:当编译时提示找不到该属性时,可以Rebuild一下试试。

 

7.使用类方法

public class Utils {
    @BindingAdapter({"imageUrl"})
    public static void setImageUrl(ImageView imageView, String url){
        Log.e("tag",url);
    }


    public static String toLower(String str){ //使用这个方法
       return str.toLowerCase();
    }
    
}


xml中:




 

8.空合并运算符 ??



当goodsInfo.info为空时,使用goodsInfo.details

9.属性控制



当goodsInfo.tag 不为空时,使用goodsInfo.name,否则使用 goodsInfo.details

10. include 和 ViewStub

layout_include.xml




    
        
        
    

    

        

        



    

 

activity_main.xml

 

            
        

绑定数据:

person = new Person();
person.name.set("小王");
person.address.set("南方");
person.info.set("阴雨绵绵");
binding.setPerson(person);

 

使用viewStub

 

            
        
 ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        View view = binding.viewstub.getViewStub().inflate();
        person = new Person();
        person.name.set("小王");
        person.address.set("南方");
        person.info.set("阴雨绵绵");
        binding.setPerson(person);

 

 

你可能感兴趣的:(Android)