DataBinding的简单使用

DataBinding的用法

  • 是时候抛弃ButterKnife,拥抱DataBinding了。 1.ButterKnife对组件化方案支持不如DataBinding 2.ButterKnife只支持View绑定,不支持数据绑定 3.DataBinding是Google出品。 就算只看第三条,你也知道选哪一个了吧 (手动滑稽)下面还有更多DataBinding的优势

启用DataBinding

android {
	dataBinding {
		enabled true
		}
}
复制代码

注意:如在lib中也使用DataBinding也须要在build文件中添加php


DataBinding 的基本使用

数据绑定

咱们建立一个User类,User有两个属性:name和age。java

public class User {
    private String name;
    private int age;
    public User() {
        this.name = "小花";
        this.age = 18;
    }
    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; }
}
复制代码

也能够这样写android

public class User {
    public String name;
    public int age;
}
复制代码

而后咱们想把User这个对象的两个属性绑定在xml控件中,咱们建立一个activity_main.xml文件.由于age属性是int类型,而textView.setText()不容许使用int,因此,咱们能够在后面拼上字符标志``git

<?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">
    <data>
        <variable name="user" type="com.example.ding.databindingdemo.User" />
    </data>
    <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" />
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.age+`岁`}" />
    </LinearLayout>
</layout>
复制代码

而后咱们在Activity中获取xml对应的DataBinding对象,并对其进行赋值github

private ActivityMainBinding mBinding;//这个对象是根据activity_main.xml命名规则自动生成的,继承自ViewDataBindig了;类
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        mBinding.setVariable(BR.user,new User());
        //或者
        mBinding.setUser(new User());
        mBinding.executePendingBindings();
    }
复制代码

fragment这样绑定DataBindingUtil.inflate(inflater,R.layout.fragment_home,container,false);数组

是否是很简单?这还简单的,看的我头皮发麻,两眼发晕,我不须要绑定什么数据,我就想跟ButterKnife用法同样。好,下面就知足你 ###控件绑定 咱们在xml中为每一个你须要拿到的控件命名ID架构

<Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" />
复制代码

那咱们应该怎么拿到对应的控件呢?就是咱们的ViewDataBinding的子类,生成的ActivityMainBindingButton mBinding.mainBtn(生成规则遵循Java驼峰命名),这样咱们就能够拿到这个按钮了,以后的事情就不用我说了把。 ##方法绑定app

<Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick"/>
复制代码

之前咱们能够这样写点击事件,而后在activity中定义public void onClick(View view) { }方法,而后在这里面对点击事件进行处理。如今,咱们能够对这个点击事件作任何方法的跳转。传入类,mBinding.setVariable(BR.act,this);而后传入类方法android:onClick="@{()->类对象.类方法(参数para)}"框架

<variable name="act" type="com.example.ding.databindingdemo.MainActivity"/>
        <Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{()->act.getName(user.name)}"/>
复制代码

咱们在activity中定义的方法public void getName(String name){ //todo }。固然,你也能够导入其余类。例如定义MyHandlerside

public class MyHandlers {
    public void getName(String name) { ... }
}
复制代码

布局文件就要这样写。

<variable name="handler" type="com.example.ding.databindingdemo.MyHandlers"/>
        <Button android:id="@+id/main_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="@{()->handler.getName(user.name)}"/>
复制代码

注意:要在Activity中传入MyHandlers实例,否则会报空指针。 ##自定义方法Binding adapters 有些控件不能直接传数据就能展现,例如ImageView,RecyclerView之类。咱们能够用BindingAdapter注解来自定义方法,xml中使用方式:

<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" bind:imageUrl="@{user.pic}" />
复制代码

新建一个java类,类名随意。类方法需为static@BindingAdapter注解标记该方法,valueStirng[],xml中使用的atts与里面的命名规则一致。requireAll是否必须传。而后在setImageUrl方法中获取view和url参数,而后进行展现。固然url也能够替换为src或者bitmap

public class ImageBindingAdapter {
    @BindingAdapter(value = {"bind:imageUrl"},requireAll = true)
    public static void setImageUrl(ImageView view,String url){ 
        Glide.with(view.getContext()).load(url).into(view);
    }
   @BindingAdapter(value = {"bind:imageSrc"},requireAll = true)
    public static void setImageSrc(ImageView view,int src){
        view.setImageResource(src);
    }
    @BindingAdapter(value = {"bind:imageBitmap"},requireAll = true)
    public static void setImageBitmap(ImageView view,Bitmap bitmap){
        view.setImageBitmap(bitmap);
    }
}
复制代码

假如你写了一个自定义控件,你也能够用@BindingAdapter绑定你的数据源。例如,我写了一个MyLinearLayout来实现ListView,而后我写了一个text_list方法来传递数据。

<com.ding.example.MyLinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" bind:text_list="@{user.datas}" />
复制代码

java代码

public class LinearLayoutBindingAdapter {
    @BindingAdapter(value = {"bind:text_list"},requireAll = true)
    public static void setDataResource(MyLinearLayout layout,List datas){ 
        layout.setDataList(datas);
    }
复制代码

这样,咱们就把数据源传到咱们的MyLinearLayout中,而后在咱们自定义的LinearLayout中对数据作处理了。 ##双向绑定 双向绑定使用@={}就能够实现了。没错,就是这么简单。例如,EditText中双向绑定了user.job这个属性,当editText中内容发生更改时,绑定的数据user.job也会更新,经过mBinding.getUser().job就能够拿到最新的数据了。 ##表达式

  • 数学运算符: + - / * %
  • 字符串拼接: +
  • 逻辑运算符: && ||
  • 二进制: & | ^
  • 一元运算符: +
  • 位运算符: >> >>> <<
  • 比较: == > < >= <=
  • instanceof
  • ()<
  • 数据类型: character, String, numeric, null
  • 类型转换(ClassCast)
  • 方法回调(Method calls)
  • 数据属性
  • 数组:[]
  • 三元操做符:? ##与LiveData连用 LiveData是谷歌新推出的一个可被观察的数据持久化的控件,一般出如今ViewModel中,是用用MVVM架构。有兴趣的看一下个人上一篇文章基于Google MVVM框架的baseMVVM框架LiveData遵循其余应用程序控件的生命周期,例如Activity,Fragment或Service。此感知确保LiveData仅更新处于活动生命周期状态的应用程序控件观察者,不会形成内存泄漏。具体是用请参考官方文档
  • 注意:DataBinding需调用setLifecycleOwner(LifecycleOwner lifecycleOwner)以后,绑定了LiveData数据源的xml控件才会随着数据变化而改变。
  • 注意:LiveData暴露公开两个方法用于设置值: 1.postValue:容许后台线程向主进程推送数据 2.setValue:只容许在主线程调用,若是在其余线程调用会报错:This method must be called from the main thread 最后奉上demo的github地址 https://github.com/dingdaidao/DataBindingDemo
相关文章
相关标签/搜索