美文网首页AndroidAndroid模块开发
解决组件化开发butterknife 在 library中使用的

解决组件化开发butterknife 在 library中使用的

作者: Flynn_X | 来源:发表于2017-04-08 11:49 被阅读7059次

在Android开发中butterknife是一个很好的对资源初始化的工具,它可以使你的代码简洁通俗易懂,同时配合Android ButterKnife Zelezny插件可以让你写代码的速度提升至少20倍。

在一般app中我们都是单组件开发,什么意思呢,你只有一个主moduel,所有代码不管是java,xml,资源,依赖库都在app中,这个时候使用butterknife是非常简单的,如GitHub地址描述照着做就可以了。

  • 第一步
    在app底下的build.gradle中添加这两个依赖。
dependencies {
  compile 'com.jakewharton:butterknife:8.5.1'
  annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}
  • 第二步
    在activity中如图使用即可,别忘了在oncreate方法中添加 ButterKnife.bind(this);
class ExampleActivity extends Activity {
  @BindView(R2.id.user) EditText username;
  @BindView(R2.id.pass) EditText password;
...
}

一切顺其自然,一般照着做都不会有问题。

  • 重点是当你想对项目进行组件化开发时,butterknife的使用就不是那么简单了,当然GitHub上也有说明怎么在library中使用方法,我和多数人情况一样最终发现照着作者的使用示例不管你怎么调整都将是一个大坑,最终都是无法使用。github上也有很多反馈,发现所有人都是一脸懵逼,连作者都是一脸懵逼。
11491621699_.pic_hd.jpg

下面介绍根据我无限尝试总结出的在组件化开发中library中如何使用butterknife.

  • 首先不能像github地址描述的那样使用依赖,在全局build.gradle 中请这样写,特别注意版本,不要使用最新的8.5.1 而应该使用8.4.0,不要问我为什么。
buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
  • 在library里正常引入butterknife,这里可以使用最新版本8.5.1。
    1、在library中build.gradle中引入插件
    apply plugin: 'com.jakewharton.butterknife'
    2、 dependencies 中添加依赖
dependencies {
  compile 'com.jakewharton:butterknife:8.5.1'
  annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
}

到此使用前期工作就算做完了,下面介绍在library中如何使用和注意事项。

  • butterknife在library activity中的使用和注意事项
    1、用R2代替R findviewid
 @BindView(R2.id.textView)
    TextView textView;
    @BindView(R2.id.button1)
    Button button1;
    @BindView(R2.id.button2)
    Button button2;
    @BindView(R2.id.button3)
    Button button3;
    @BindView(R2.id.image)
    ImageView image;

2、在click方法中同样使用R2,但是找id的时候使用R。

 @OnClick({R2.id.textView, R2.id.button1, R2.id.button2, R2.id.button3, R2.id.image})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.textView:
                break;
            case R.id.button1:
               
                break;
            case R.id.button2:
                break;
            case R.id.button3:
                break;
            case R.id.image:
                break;
        }
    }

3、特别注意library中switch-case的使用,在library中是不能使用switch- case 找id的,解决方法就是用if-else代替。

  @OnClick({R2.id.textView, R2.id.button1, R2.id.button2, R2.id.button3, R2.id.image})
    public void onViewClicked(View view) {
        int i = view.getId();
        if (i == R.id.textView) {
        } else if (i == R.id.button1) {
        } else if (i == R.id.button2) {
        } else if (i == R.id.button3) {
        } else if (i == R.id.image) {
        }
    }

2018-01-02更新

本篇文章写了比较久了,发现大部分人还是明白问题所在,也还有少数新同学不大明白我所描述的内容,期间有很多同学或者底下留言或者qq咨询过我,我觉得在2018新的一年有必要将问题描述的更清楚。故接下来我将通过demo详细讲解,后面也会附上可运行demo。

同时也预告下在新的一年我将写一系列文章和大家互相学习组件化开发。实战中将详细讲解如何维护那不堪入目的代码,如何通过更新一个版本做到将原有看起来很丑的不适配沉浸栏的界面通过你的组件化变的高大上。重点解决以下几个问题:

  • 组件化框架结构(Mvp、rxjava2、retrofit2、dagger2、arouter、ButterKnife 、rxbus 等的组合使用)
  • 哪些可以独立library
  • 前辈将请求写死了,并且用了很老的框架,现在加功能很痛苦怎么办等等

以上都是实战中我所总结的,希望自己能够将微薄经验和大家一起分享,同时有机会和所有人共同学习。

下面开始讲解demo。

  • gradle配置ButterKnife


    image.png
  • 主Module使用


    image.png
  • 副module(library)中使用


    image.png
  • 注意问题
    特别注意:当副Module使用R2时候可会报红,没关系,rebuild 就好了
    强烈建议大家 用插件 Android ButterKnife Zelezny 生成 然后在library中根据每个地方修改成R2。

image.png

自此介绍完毕,下面放出ButterKnifeDemo链接。

到此butterknife在library中如何使用,其中有什么坑就算全部介绍完了,希望对你组件化开发有所帮助,如有其他疑问欢迎底下留言。

相关文章

网友评论

  • 流水不腐小夏:使用databinding吧
    Flynn_X:@流水不腐小夏 多谢推荐,databing确实是一个很好的绑定数据的组件,新项目考虑结合databing.
  • sunrise10:主要是单独的模块单独运行的时候会出问题很烦
    Flynn_X:@sunrise10 确实是,这个用多了还好,不会为爆红而担心什么。
  • ChrisSen:感谢楼主的文章,解决了我的问题!
  • 代码君_Coder:谢谢楼主的文章,获益匪浅
  • 松小白:你好楼主,我可以使用R2 ,但是还是依然找不到控件,控件是null。
    83b1ce4c4ba5:可以的,需要重新导包
  • 黑马有点白986:写错了吧,switch的是常量,R不是常量。
  • 段浅浅儿:博主您好,请教一个问题:
    我想把通用的三方库放在一个baseLibrary,然后被其他 moduel 依赖, 于是在 baseLibrary 中使用了集成了 butterknife ,我在主Moduel中可以引用到 butterknife 的方法,但是会报 NullPointerException。
    我看了博主放在 github 的 demo,发现您在主 moduel 中也添加了 butterknife 的依赖。请问,为什么主Moduel 中可以使用 butterknife ,但是却报空指针?
    段浅浅儿:@CeleryIce 嗯嗯,谢谢楼主回复。
    Flynn_X:@DRPrincess 要使用butterknife必须在任何一个module 都添加依赖,然后就是注意R2的使用。
  • 段浅浅儿:感谢分享,并期待博主的组件化系列
  • 462191cfd704:你好,Android studio 3.0 library 中使用butterknife怎么用呢?Android studio 3.0 不能使用android apt插件
    462191cfd704:@CeleryIce 谢谢,弄好了
    Flynn_X:请参考我写的demo , 这里没有用apt, https://github.com/CeleryIce/ButterKnifeDemo
  • 2f16617a6130:组件开发在library中使用butterknife,已经绝望怀疑人生。
    Flynn_X:@好好看好好学_392e 你可以参照我github 放的demo使用,有什么不了解的加我qq吧:2596449399
    好好看好好学_392e:前辈library中怎么用butterknife,我已经要疯了
    Flynn_X:习惯就好:stuck_out_tongue_winking_eye: 我的上线应用就一直用butterknife,其实也没什么。
  • 2f16617a6130:刚才看了下github作者主页,提到的解决办法跟楼主说的一样也是用R2替代R,不过每提点击事件不能用switch case,看楼主是8.4版本,会不会更新下,用8.8.1,switch的bug就解决了。
    Flynn_X:@ComeOverSky 可以的,switch ..case 在library中所有版本都是不可用的,具体看报错,至于使用R2,为什么找不到对应的id,暂时还不知道原因。
    2f16617a6130:as 3.0+butterknife 8.8.1不适配
  • fef3a2360375:试过了,还是不行,只是打成lib的时候不报错了,但是引用的时候还是报找不到id,请问楼主怎么解决
    Flynn_X:你好,我更新了文章,写了demo,请跳转到github中下载查看,如还有问题,欢迎底下留言。
  • 皇马船长:用R2代替R ??

    这个要手动替换吗
    34099e6c6895:你的意思是lib app切换 每次都要手动切换R R2?
    皇马船长:@CeleryIce 不是吧,这么坑 ??
    Flynn_X:是的,手动替换
  • d8cc2efbda3e:请问 单独切换组件的时候,是将R2 改成 R 吗?
    Flynn_X:@Ausp1cious 也就是你整个app只有一个主module(默认创建的app结构)这种就不用使用这里的设置,参照butterknife github 开源项目设置即可,如果是将业务模块module作为library 那就一样的参照我这里的设置,用R2。
    d8cc2efbda3e: @CeleryIce 业务模块作为一个单独的app
    Flynn_X:@Ausp1cious 你这里指单独切换组件是什么意思
  • 小欧lq:lib改成R2编译没问题,但是点击事件的判断某个控件的点击事件的时候System.out.println(view.getId()+"---"+R2.id.btn_register);这个2个值打印出来不一样
    Flynn_X:请仔细看上面的代码判断点击的时候if(view.getId()==R.id.btn_register),不是R2
  • 李科吐温:问题主一个不是很相关的问题,就是组件化过程中,副model们中需要在application中初始化的代码需要怎么去初始化,因为副model们没有application
    csxiong:MVPArms其中一个GlobalConfig 去看下ConfigModule,他的解决方案就符合你的需求,就是和楼上说的方式类似,写一个配置类,然后Application去扫描包下所有configModule的类,加载到Application中
    皇马船长:副module中 在开始时也可以有一个application,只不过不能强引用这个类,并且在集成模式时候把这个类exclude
    Flynn_X: @李科吐温 对于这个问题我是这样做的,在相应module下写一个类,用一个方法包含所有要初始化的东西,在主module中初始化这个方法,希望对你有帮助。
  • jiantaocd:赞一个,问题解决。
    Flynn_X: @jiantao88 多谢支持
  • stefanli:能保证R文件里面的值和R2文件里面的值完全相同么?
    Flynn_X: @stefanli 可以的,我项目中就这么用的,从编译到打包都没什么问题。
  • 说变就变_3540:写的很好…赞一个!!!

本文标题:解决组件化开发butterknife 在 library中使用的

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