介绍
ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象,有了ButterKnife可以很轻松的省去这些步骤。使用ButterKnife对性能基本没有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class。
GitHub地址:https://github.com/JakeWharton/butterknife
原理
利用了IOC的(Inverse of Controll)控制反转结构,2004年后改名为DI(dependency injection)依赖注入。目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性。越来越趋向于后端开发了。
配置
在Android Studio项目中配置使用ButterKnife
本文介绍使用的as版本为3.1.2,ButterKnife版本为8.8.1
1.如果你是直接在app中使用,只需在app的 build.gradle 中添加如下代码:
dependencies {
implementation 'com.jakewharton:butterknife:10.2.3'
annotationProcessor'com.jakewharton:butterknife-compiler:10.2.3'
}
1
2
3
4
2.如果你是在Library库中使用,按照github上的配置来写,会报错。
Unable to find method 'com.android.build.gradle.api.BaseVariant.getOutputs()Ljava/util/List;'.
Possible causes for this unexpected error include:<ul><li>Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
Re-download dependencies and sync project (requires network)</li><li>The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
Stop Gradle build processes (requires restart)</li><li>Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.</li></ul>In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.
1
2
3
4
在网上找到了大神的解决办法解决组件化开发butterknife 在 library中使用的坑
第一步
配置项目根目录的build.gradle
这里注意butterknife的版本,我从8.8.1一直往下降,到了8.5.1才可以使用
第二步
配置library中的build.gradle
顶部添加插件apply plugin: ‘com.jakewharton.butterknife’
在dependencies中添加和在app中的一样
到此配置已完成,下面说下在library中使用时注意事项
1.用R2代替R,这点butterknife的开发者也做了说明
@BindView(R2.id.test_tv)
TextView tv;
@BindView(R2.id.test_btn)
Button btn;
1
2
3
4
2.onclick事件,在library中不能用switch,如果使用,点击事件会失效,用if和else代替。还要注意id的使用
安装插件
安装后重启生效
使用时,右键layout->点击Generate->Generate ButterKnife Injections
注解使用用例
绑定id:BindView
@BindView(R.id.login_btn_login)
Button btn_login;
1
2
Adapter中ViewHolder使用,注意:是this
public static class LocationViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.location_show)
TextView locationShow;
@BindView(R.id.statement_show)
TextView stateementShow;
@BindView(R.id.time_show)
TextView timeShow;
@BindView(R.id.spend_money_show)
TextView spendMoneyShow;
@BindView(R.id.spend_time_show)
TextView spendTimeShow;
public LocationViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
Button点击事件:@OnClick
@OnClick({R.id.login_btn_login})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.login_btn_login:
break;
default:
break;
}
}
1
2
3
4
5
6
7
8
9
10
CheckBox点击事件:@OnCheckedChanged
@OnCheckedChanged({R.id.login_cb_remember_password, R.id.login_cb_auto_login})
public void onViewCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
switch (compoundButton.getId()) {
case R.id.login_cb_remember_password:
if (isChecked) {
} else {
}
break;
case R.id.login_cb_auto_login:
if (isChecked) {
} else {
}
break;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
RadioButton点击事件:@OnClick
@OnClick({R.id.rb_man, R.id.rb_woman})
public void onViewCheckedChanged(RadioButton radioButton) {
boolean checked = radioButton.isChecked();
switch (radioButton.getId()) {
case R.id.rb_man:
if (checked) {
}
break;
case R.id.rb_woman:
if (checked) {
}
break;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ViewPager事件监听:@OnPageChange
@OnPageChange(R.id.viewpager)
public void onPageSelected(int position) {
switch (position) {
case 0:
break;
case 1:
break;
}
}
1
2
3
4
5
6
7
8
9
10
11
点击事件onclick,不需要在xml中写οnclick= “方法名”,区别于MVVM的databinding
@BindView(R.id.tv_sure) public TextView tvSure; @BindView(R.id.tv_cancel) public TextView tvCancel; ButterKnife.bind(view); @Optional @OnClick({R.id.tv_cancel, R.id.tv_sure}) public void OnTextClick(View tv){ int id = tv.getId(); Log.i(TAG, "OnTextClick"); if (id == R.id.tv_cancel){ //弹框消失 hidePopupWindow(); }else if (id == R.id.tv_sure){ thirdAppMgr.insertAddedApp(mChooseAppsAdapter.getNewAppInfos()); } } <TextView android:id="@+id/tv_sure" android:layout_width="100dp" android:layout_height="50dp" android:layout_marginLeft="100dp" android:text="确定" android:background="@color/teal_200" android:gravity="center"/> <TextView android:id="@+id/tv_cancel" android:layout_width="100dp" android:layout_height="50dp" android:text="取消" android:gravity="center" android:layout_marginLeft="30dp" android:background="@color/purple_200"/>