美文网首页Android-Data BindingiOS developAndroid技术知识
Data Binding Component详解 - 换肤什么的

Data Binding Component详解 - 换肤什么的

作者: MarkZhai | 来源:发表于2016-07-25 11:19 被阅读1014次

    上一篇从零开始的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。

    对应的接口有:

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

    创建Component

    声明抽象adapter

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

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

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

    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:

    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:

    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:

    public class ProductionComponent implements DataBindingComponent {
    
        private MyBindingAdapter mAdapter = new ProductionBindingAdapter();
    
        @Override
        public MyBindingAdapter getMyBindingAdapter() {
            return mAdapter;
        }
    }
    

    测试环境Component:

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

    使用

    layout

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

    <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很简单,我们做全局的注入只需要调用:

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

    重新创建activity

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

    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做关联呢?很简单,只需要作为方法的第一个参数就可以了:

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

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

    其使用场景很多,如:

    • 换肤
    • 打点
    • 替换原生属性
    • 等等

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


    欢迎加入QQ群:568863373。

    欢迎关注我们的公众号:魔都三帅,欢迎大家来投稿~只需要是未在微信平台上发布过的技术相关类文章都可以哦(不局限于任何语言和平台)。

    公众号

    相关文章

      网友评论

        本文标题:Data Binding Component详解 - 换肤什么的

        本文链接:https://www.haomeiwen.com/subject/pkmgjttx.html