您的位置:首页 > 其它

Data Binding Component详解 - 换肤什么的只是它的一个小应用!

2017-12-27 13:25 423 查看
上一篇从零开始的Android新项目8 - Data Binding高级篇中,我们提到了使用Component来进行注入,以方便进行测试的功能,有一些朋友说写的不够清楚,还有些疑惑,所以本篇就来详细说说Component。

作为例子,我们的实现目标是使用Data Binding Component,让应用全局的TextView的文本都能随时变成test,还能进行全局换肤。

代码位于DataBindingSample里面的component包下。

DataBindingComponent接口

build/intermediates/classes
下面,可以找到
DataBindingComponent
类,包名为
android.databinding
,全局只会有一个该类——此接口在编译时生成,包含了所有用到的实例BindingAdapters的getter方法。

当一个BindingAdapter是一个实例方法(instance method),一个实现该方法的类的实例必须被实例化。这个生成的接口会包含每个声明BindingAdapter的类/接口的get方法。命名冲突会简单地加一个数字前缀到get方法前来解决。

如果使用Dagger 2,开发者可以继承这个接口,并把继承的接口注解为Component。

对应的接口有:

setDefaultComponent(DataBindingComponent))

inflate(LayoutInflater, int, ViewGroup, boolean, DataBindingComponent)), inflate一个binding layout并返回新创建的binding

bind(View, DataBindingComponent)), 根据给定的layout root返回binding,如果没有则创建

第一个接口全局起作用,后两个接口仅对该语句inflate的布局起作用。

创建Component

声明抽象adapter

如果不需要实现多个Component,可以直接跳过这一步。

我们声明一个抽象的adapter,在其中写上抽象方法来设置我们想要做data binding的属性,这里我们直接干掉了TextView的android命名空间下的text和textColor两个属性。

这里的
@BindingAdapter
注解会让data binding在component中生成我们这个adapter的get方法(必须是非静态的)。

12345678
public abstract class MyBindingAdapter {    @BindingAdapter("android:text")    public abstract void setText(TextView view, String value);    @BindingAdapter("android:textColor")    public abstract void setTextColor(TextView view, int value);}

实现adapter

我们继承
MyBindingAdapter
分别实现两个adapter:

ProductionBindingAdapter.java
:

123456789101112
public class ProductionBindingAdapter extends MyBindingAdapter {    @Override    public void setText(TextView view, String value) {        TextViewBindingAdapter.setText(view, value);    }    @Override    public void setTextColor(TextView view, int value) {        view.setTextColor(value);    }}
TestBindingAdapter.java:


123456789101112131415161718
public class TestBindingAdapter extends MyBindingAdapter {    @Override    public void setText(TextView view, String value) {        view.setText(value + " test");    }    @Override    public void setTextColor(TextView view, int value) {        if (value == view.getContext()                .getResources()                .getColor(R.color.textColorDay)) {            view.setTextColor(view.getContext()                    .getResources()                    .getColor(R.color.textColorNight));        }    }}
前者使用的是原来的设置,后者则分别给text加上了” test”后缀,并做了color的转换,实现了字体颜色的“换肤”功能。

实现component

在写了上面的代码后,再看看
DataBindingComponent
,会发现里面多了一个接口方法,遂实现之:

生产环境Component:

123456789
public class ProductionComponent implements DataBindingComponent {    private MyBindingAdapter mAdapter = new ProductionBindingAdapter();    @Override    public MyBindingAdapter getMyBindingAdapter() {        return mAdapter;    }}
测试环境Component:

123456789
public class TestComponent implements DataBindingComponent {    private MyBindingAdapter mAdapter = new TestBindingAdapter();    @Override    public MyBindingAdapter getMyBindingAdapter() {        return mAdapter;    }}

使用

layout

原先的text和textColor属性并没有通过data binding设置,我们要给它们套上
@{}
:

123456
<Button    android:layout_width="match_parent"    android:layout_height="50dp"    android:onClick="@{presenter.onClickSimpleDemo}"    android:text="@{@string/demo_simple}"    android:textColor="@{@color/textColorDay}"/>

注入component

注入Component很简单,我们做全局的注入只需要调用:

12345
if (DemoApplication.isTest) {    DataBindingUtil.setDefaultComponent(new ProductionComponent());} else {    DataBindingUtil.setDefaultComponent(new TestComponent());}

重新创建activity

由于点击事件在
MainActivity
创建后才触发,所以这个activity上并不会起作用,我们需要重新创建它:

123456789
public void onClickInjectDemo(View view) {    if (DemoApplication.isTest) {        DataBindingUtil.setDefaultComponent(new ProductionComponent());    } else {        DataBindingUtil.setDefaultComponent(new TestComponent());    }    DemoApplication.isTest = !DemoApplication.isTest;    recreate();}
设置后
recreate()
即可。可以看demo工程的效果,点击最后的按钮后,字体颜色发生变化,textview的text后面都加上了test字符串。

静态adapter方法

那么静态的BindingAdapter方法怎么去和Component做关联呢?很简单,只需要作为方法的第一个参数就可以了:

12345
@BindingAdapter("android:src")public static void loadImage(TestComponent component,                             ImageView view, String url) {    /// ...}

本篇我们实践了Data Binding中比较高级的特性:Component。

其使用场景很多,如:

换肤

打点

替换原生属性

等等

欢迎大家发挥自己的想象力,补充更多的使用场景。

转自:http://blog.zhaiyifan.cn/2016/07/21/data-binding-component/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: