一、引言
ButterKnife(黄油刀)是一个专注于Android系统的View注入框架,以前操作控件总是要写很多findViewById来找到View对象,控件的少的时候我们还能接受,控件多起来有时候就会有一种想砸键盘的冲动。但有了ButterKnife可以很轻松的省去这些步骤,也让代码变得更加简洁,便于维护。目前使用很广,最重要的一点,使用ButterKnife对性能基本没有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class。项目集成起来也是特别方便,使用起来也是很简单。
二、ButterKnife介绍
- 官网:ButterKnife
- GitHub:ButterKnife
ButterKnife 所提供了一种能力--使用注解生成模板代码,将view与方法和参数绑定。在Android编程过程中,我们会写大量的布局和点击事件,像初始view、设置view监听这样简单而重复的操作让人觉得麻烦类,所以可以采用注解的方式去实现,而ButterKnife则是注解中相对简单易懂的很不错的开源框架。Github上有21K个star(截止201808),配合 AndroidStudio 提供的 ButterKnife 插件,帮助开发者省却了频繁findviewbyid的烦恼,最新的 ButterKnife 还提供了onclick绑定以及字符串的初始化,使用者可以查阅 ButterKnife 以及 ButterKnife 插件进一步了解!
ButterKnife 优势:
- 强大的View绑定和Click事件处理功能,简化代码,提升开发效率
- 方便的处理Adapter里的ViewHolder绑定问题
- 运行时不会影响APP效率,使用配置方便
- 代码清晰,可读性强
三、ButterKnife使用
当前项目所使用的是7.0版本,而最新为8.X版本,8.X版本方法名有所改动,建议看官方文档,整体业务逻辑和原理没什么变动。
3.1 基本配置
在Project或Module中的build.gradle导入ButterKnife:
implementation 'com.jakewharton:butterknife:7.0.0'
3.2 插件安装(zelezny)
打开插件栏目,使用快捷点Ctrl+Alt+s 打开或者通过菜单栏(工具栏File->Settings),搜索zelezny,下载插件并安装,完成后重启Android Studio:
插件安装确认:
需要将光标移到setContentView(R.layout.activity_main),将光标放到R.layout.activity_main,然后右键Generate:
选择Generate ButterKnife Injections:
有如上菜单,可以确认插件已安装成功。然后选择控件:
3.3 ButterKnife的注册与注销
在Activity中绑定ButterKnife:
由于每次都要在Activity中的onCreate绑定Activity,所以建议在BaseActivity完成绑定,子类继承即可。绑定Activity 必须在setContentView之后。使用ButterKnife.bind(this)进行绑定。
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
......
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.bind(this).unbind();
}
在Fragment中绑定ButterKnife:
Fragment的生命周期不同于activity。在onCreateView中绑定一个Fragment时,在onDestroyView中将视图设置为null。当你调用bind来为你绑定一个Fragment时,ButterKnife会返回一个Unbinder的实例。在适当的生命周期(onDestroyView)回调中调用它的unbind方法进行Fragment解绑。使用ButterKnife.bind(this, view)进行绑定。
private Unbinder unbinder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main_fragment, container, false);
//返回一个Unbinder值(进行解绑),注意这里的this不能使用getActivity()
unbinder = ButterKnife.bind(this, view);
return view;
}
/**
* onDestroyView中进行解绑操作
*/
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
在Fragment中调用,必须成双成对。
在Adapter中绑定ButterKnife:
在Adapter的ViewHolder中使用,将ViewHolder加一个构造方法,在new ViewHolder的时候把view传递进去。使用ButterKnife.bind(this, view)进行绑定。
static class ViewHolder {
@BindView(R.id.title) TextView name;
@BindView(R.id.content) TextView content;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
3.4 ButterKnife的绑定
ButterKinfe的注解标签因版本不同而有所变化。8.0之前的Bind标签在8.0之后变成了BindView,而8.7之后在绑定view时,要用R2.id.XXX而不再是常用的R.id.XXX了。
控件的绑定:
控件id的注解:
@Bind() //7.0的用法
@BindView() //8.0的用法
//7.0
@Bind(R.id.edt_uuid)
EditText edtUuid;
//8.0
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindString(R2.string.app_name) //绑定资源文件中string字符串
String str;
@BindColor( R2.color.colorAccent ) //具体色值在color文件中
int black ; //绑定一个颜色值
事件绑定:
绑定控件点击事件:@OnClick( )
@OnClick(R2.id.start ) //给 start 设置一个点击事件
public void showToast(){
......
}
指定多个id绑定事件:
@OnClick({R.id.tv_send,R.id.tv_connect})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.tv_send:
......
break;
case R.id.tv_connect:
......
break;
}
}
3.5 注意事项
ButterKnife使用很简单,但也要注意以下几点:
- 在Activity 类中绑定 :ButterKnife.bind(this);必须在setContentView();之后绑定;且父类bind绑定后,子类不需要再bind
- 在非Activity 类(eg:Fragment、ViewHold)中绑定: ButterKnife.bind(this,view);这里的this不能替换成getActivity()
- 在Activity中不需要做解绑操作,在Fragment 中必须在onDestroyView()中做解绑操作
- 使用ButterKnife修饰的方法和控件,不能用private or static 修饰,否则会报错。错误: @BindView fields must not be private or static
- setContentView()不能通过注解实现。(其他的有些注解框架可以)
- 使用Activity为根视图绑定任意对象时,如果你使用类似MVC的设计模式你可以在Activity 调用ButterKnife.bind(this, activity),来绑定Controller
- 使用ButterKnife.bind(this,view)绑定一个view的子节点字段。如果你在子View的布局里或者自定义view的构造方法里 使用了inflate,你可以立刻调用此方法。或者,从XML inflate来的自定义view类型可以在onFinishInflate回调方法中使用它。