Android DataBinding学习和实践(二)

书承上文,这次我们来探究一下DataBinding中控件事件的绑定和可观察对象的使用。

目录

一、自定义DataBinding生成类名以及import的使用

1、自定义DataBinding生成类名

2、import的使用

二、DataBinding中控件事件绑定

三、Observable Data Object(可观察数据对象)

1、Observable Field

2、Obserable Collections

3、Obserable Object


一、自定义DataBinding生成类名以及import的使用

1、自定义DataBinding生成类名

        在上篇文章中我们使用了一个名为ActivityMainBinding的类,这个类是DataBinding通过布局文件名称来生成的,规则是将布局文件的下划线去掉,每个单词首字母大写并且加上Binding后缀。但是,这样生成的名字有可能不符合实际开发的命名规则,因此,我们可以自定义生成名称。

        首先,我们在布局文件的<data>标签里设置它的class属性,如下

<data class="MainBinding">
        <variable
            name="user"
            type="com.silencer.db.entity.User" />
        <variable
            name="arr"
            type="String[]" />
    </data>

        这样,系统给我们生成的类名就是MainBinding了,它位于**.databinding包下,如图

         这里的MainBindingImpl继承MainBinding的类。同时,我们可以修改<data>的class值的形式来设置生成类在不同的包下等等。如<data class=".MainBinding">代表MainBinding位于根目录包下。

2、import的使用

        在布局文件中,如果引入的变量包名过长,那么会很影响阅读。因此,我们可以使用import来导入某类。如下

<data class="MainBinding">
        <import type="com.silencer.db.entity.User"/>
        <variable
            name="user"
            type="User" />
        <variable
            name="arr"
            type="String[]" />
    </data>

        可以发现,在使用import导入之后,我们对变量user的声明变得很简洁。同时,使用import导入某个类之后,我们可以很简洁的使用它的静态变量和方法,如下 可以看到我们在text的属性中引用了User类的静态变量Tag。

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/main_text"
            android:text='@{User.TAG}'
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        如果引入多个类时,可能会发生冲突,这个时候就可以通过指定import的alias属性来给它设置一个别名,如下所示将User改名为People

<data class="MainBinding">
        <import type="com.silencer.db.entity.User" alias="People"/>
        <variable
            name="user"
            type="People" />
        <variable
            name="arr"
            type="String[]" />
    </data>

二、DataBinding中控件事件绑定

        DataBinding的强大之处不仅在于可以动态绑定数据,而且还可以绑定控件的事件。我们以TextView的点击事件为例,使用三种方法来进行绑定。

①布局对应Activity的方法

        我们首先在主函数中实现一下View.OnClickListener接口的onClick方法,如下

 switch (v.getId()){
            case R.id.main_text:
                Toast.makeText(MainActivity.this,"点击了文本",Toast.LENGTH_SHORT).show();
                break;
        }

        然后在布局文件中绑定这个事件,如下所示

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/main_text"
            android:text='@{People.TAG}'
            android:onClick="onClick"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        可以看到onclick属性中填入了onClick,这个值就是activity中匹配点击事件的接口。我们运行一下看看结果。

点击前
点击后

②自定义类成员方法

        我们新建一个类,类名为TVEvent,如下

public class TVEvent {
    public static void tvClick1(View v){
        ((TextView)v).setText("通过tvClick1点击事件");
    }
    
    public void tvClick2(View v){
        ((TextView)v).setText("通过tvClick2点击事件");
    }
}

        该类有一个公共的静态方法和一个公共的成员方法。我们在布局文件中引入这个类并声明变量。

......
    <import type="com.silencer.db.callback.TVEvent"/>
        <variable
            name="tvEvent"
            type="TVEvent" />
......

        我们还需要在MainActivity给这个变量赋值,这里不贴代码,不懂得可以看第一篇文章。然后我们就可以使用成员方法来实现点击事件的绑定。

......    
    <TextView
           ......
            android:text='@{People.TAG}'
            android:onClick="@{(v)->tvEvent.tvClick2(v)}"
            ....../>
......

        这里用的时lambda表达式来引用的。

③静态方法

        这里和第二点很像,只不过可以直接使用类名.静态方法来绑定,如

......    
    <TextView
           ......
            android:text='@{People.TAG}'
            android:onClick="@{(v)->TVEvent.tvClick1(v)}"
            ....../>
......

注意,使用第二第三点方法时,要注意对象方法返回值与实践匹配的方法返回值一致,如onlick的返回值是void,那么tvClick1和tvClick2的返回值都应该为void

三、Observable Data Object(可观察数据对象)

        注意,这里就是重点了。我们前面讲了这么久就是为了这一部分。DataBinding的提出就是为了使用可观察数据对象来实现动态更新。那么,什么是可观察数据对象呢?

        从字面上来看,可观察对象就是你可以观察它的变化,相当于你在现实生活中订阅了某个公众号。当公众号更新时,他就会发送信息给你,告诉你它更新了内容。同理,可观察对象就是这个“公众号”。

        可观测数据对象一般分为三类,分别为Observable Field,Obserable Collections和Obserable Object。我们一一讲解。

1、Observable Field

        Observable Field(可观察字段),是一种拥有单一字段且自包可观察的对象,有如下几种:

  • ObservableBoolean
  • ObservableByte
  • ObservableChar
  • ObservableShort
  • ObservableInt
  • ObservableLong
  • ObservableFloat
  • ObservableDouble
  • ObservableParcelable

        这些对象都是包含着对应后缀的变量值,如ObservableBoolean是一个有boolean值的可观察对象。这些变量可以供其他对象订阅,在它们发生变化时,就会通知所有的观察者更新自己的信息。我们以ObservableInt来举例说明。

        首先我们在布局文件中声明一个ObservableInt对象并将它绑定到TextView的text属性上面,如下

......
    <variable
            name="oInt"
            type="androidx.databinding.ObservableInt" />
......

......
    <TextView
           ......
            android:id="@+id/main_text"
            android:text='@{String.valueOf(oInt)}'
            android:onClick="@{(v)->tvEvent.tvClick2(v)}"
            ...... />
......

        然后我们传入要观察的ObservableInt对象,如下

......
ObservableInt oInt = new ObservableInt(0);
binding.setOInt(oInt);
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    oInt.set(oInt.get()+17);
                }
            }
        }).start();
......

        运行一下就可以看到文本在不停变动了,由于我不能截gif,所以没贴截图了。

2、Obserable Collections

        Obserable Collections(可观察集合)是一组可以被观察的对象,它可以在集合发生变化时通知观察者,例如添加元素时。使用可观察集合的方法和可观察字段相近,话不多说直接看代码。

......
     <variable
            name="list"
            type="androidx.databinding.ObservableList" />
......

......
    <TextView
            ......
            android:id="@+id/main_text"
            android:text='@{list.size()>0?list[list.size()-1]:""}'
            android:onClick="@{(v)->tvEvent.tvClick2(v)}"
            ...... />
......
......   
    ObservableList<String> oList = new ObservableArrayList<>();
     binding.setList(oList);
        new Thread(() -> {
            while (true){
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
               oList.add(System.currentTimeMillis()+"");
            }
        }).start();
......

        运行即可看见效果。

3、Obserable Object

        Obserable Object(可观察对象)是指实现Observable接口的对象,实际开发我们通常继承BaseObservable类来实现可观察对象。它可以通过在成员方法中调用notifyChange或notifyPropertyChanged来控制什么时候通知观察者发生了变化。使用方法也很简单,这里举个例子给大家说明一下。

        首先,我们创建一个类,把他命名为ObservableBook,代码如下

public class ObservableBook extends BaseObservable {
    @Bindable
    private double price;
    private String name;
    private String author;

    public ObservableBook() {
    }

    public ObservableBook(double price, String name, String author) {
        this.price = price;
        this.name = name;
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
        notifyPropertyChanged(BR.price);
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
        notifyChange();
    }
}

        这里price属性我使用notifyPropertyChanged方法来通知观察者,其他两个属性使用的时notifyChange来通知的,效果都一样。

DataBinding会生成一个BR类,他持有你声明的变量以及通过@Bindable注解标记的字段或get方法

        使用的方法和其他可观察对象一样,这里就不举例了。本文到此结束,后面会给大家介绍生命周期绑定以及双向绑定的使用。

本BLOG上原创文章未经本人许可,不得用于商业用途。转载请注明出处并告知本人,否则保留追究法律责任的权利。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值