ButterKnife|ButterKnife 使用总结

一、前言 ButterKnife 项目地址: https://github.com/JakeWharton/butterknife
ButterKnife是一个专注于Android系统的View注入框架,对性能基本没有损耗,因为ButterKnife用到的注解并不是在运行时反射的,而是编译时生成的新class。
优势:

  1. 强大的View绑定和click事件处理功能,简化代码,提高开发效率
  2. 方便处理Adapter里的ViewHolder绑定问题
  3. 运行是不会影响App效率,使用配置方便
  4. 代码清晰,可读性强
二、基本配置 【ButterKnife|ButterKnife 使用总结】步骤
  1. 在Project的build gradle中添加如下代码:
buildscript { repositories { google() jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-rc1' } }

  1. 在App的build gradle中添加如下代码:
  • 根节点添加:
apply plugin: 'com.jakewharton.butterknife'

  • dependencies中添加:
implementation 'com.jakewharton:butterknife:9.0.0-rc1' annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc1'

三、注册与绑定 1.Activity中绑定
绑定Activity必须在setContentView之后,使用ButterKinfe.bind(this)进行绑定,可以写在BaseActivity中完成绑定。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); }

2.Fragment中绑定
在onCreateView进行绑定,使用ButterKinfe.bind(this,view)方法,返回Unbinder实例,在onDestroyView中调用Unbinder的unbind()方法解绑。
public class ButterKnifeFragment extends Fragment {private Unbinder unbinder; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_butter_knife, container, false); //返回一个Unbinder值(进行解绑),注意这里的this不能使用getActivity() unbinder = ButterKnife.bind(this, view); return view; }@Override public void onDestroyView() { super.onDestroyView(); //进行解绑操作 unbinder.unbind(); } }

3.adapter中进行绑定
在ViewHolder加一个构造器,在new ViewHolder的时候吧view传递过去,使用ButterKnife.bind(this,view)进行绑定:
class ViewHolder { @BindView(R2.id.tv_butter_knife_2) TextView tvButterKnife2; @BindView(R2.id.but_butter_knife_2) Button butButterKnife2; ViewHolder(View view) { ButterKnife.bind(this, view); } } // recyclerview.viewHolder class MyHolder extends RecyclerView.ViewHolder {@BindView(R2.id.tv_butter_knife_2) TextView tvButterKnife2; @BindView(R2.id.but_butter_knife_2) Button butButterKnife2; public MyHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this, itemView); } }

四、基本使用 1.绑定view
  • 控件id注解:@BindView()
@BindView(R2.id.button) Button button;

  • 布局内多个控件id注解:@BindViews()
@BindViews({R2.id.but_test, R2.id.but_test2}) List

2.绑定资源
  • 绑定string字符串:@BindString()
@BindString(R.string.test) String strTest;

  • 绑定string里面array数组:@BindArray()
@BindArray(R.array.city) String[] citys;

  • 绑定Bitmap资源:@BindBitmap()
@BindBitmap(R.mipmap.ic_launcher) Bitmap bitmap;

  • 绑定颜色值:@BindColor()
@BindColor(R2.color.colorAccent) int colorAccent;

3.绑定事件
  • 绑定点击事件:@OnClick()
@OnClick(R.id.but_test) public void showToast() { Toast.makeText(this, "test", Toast.LENGTH_SHORT).show(); }@OnClick(R.id.but_test) public void onClick(View view){ //TODO something }@OnClick(R.id.but_test) public void onClick(Button button){ //TODO something }

  • 绑定长按点击事件:@OnLongClick()
@OnLongClick(R.id.but_test) public void onShowToast(){ Toast.makeText(this, "test", Toast.LENGTH_SHORT).show(); }

  • 指定多个id绑定事件 (此时必须使用R,使用R2只能分开写)
@OnClick({R.id.but_test, R.id.but_test2}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.but_test: Toast.makeText(this, "点击test", Toast.LENGTH_SHORT).show(); break; case R.id.but_test2: Toast.makeText(this, "点击test2", Toast.LENGTH_SHORT).show(); break; } }

-Listener中的多方法注解
如果对应的监听器有多个回调,可通过注解绑定任何一个,每一个注解都有一个它绑定的默认回调。通过指定参数替换回调。
spinner原生写法:
private void initSpinner(){ spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { //TODO }@Override public void onNothingSelected(AdapterView parent) { //TODO } }); }

通过Butter Knife 注解方法
@OnItemSelected(R.id.spinner_city) public void onItemSelected(){ // TODO }@OnItemSelected(value = https://www.it610.com/article/R.id.spinner_city,callback = OnItemSelected.Callback.NOTHING_SELECTED) public void onNothingSelected(){ // TODO }

注意事项
8.0.0之前的Bind标签在8.0.0之后变成了BindView,而8.7.0之后在绑定view时,要用R2.id.XXX而不再是常用的R.id.XXX了。
附录
绑定注解
注解 作用 使用
@BindView 绑定一个view @BindView(R2.id.test) TextView textview;
@BindViews 绑定多个view @BindViews({R2.id.test1,R2.id.test2}) List testviewList;
@BindArray 绑定string里面array数组 @BindArray(R.array.city) String[] citys;
@BindBitmap 绑定图片资源Bitmap @BindBitmap(R.mipmap.ic_launcher) Bitmap bitmap;
@BindBool 绑定boolean值
@BindColor 绑定color @BindColor(R.color.colorAccent)int collorAccent;
@BindDimen 绑定Dimen @BindDimen(R.dimen.borth_width)int borderWidth;
@BindDrawable 绑定Drawable @BindDrawable(R.drawable.test_pic) Drawable testPic
@BindFloat 绑定float
@BindInt 绑定int
@BindString 绑定一个String id 为一个String变量 @BindString(R.string.app_name)String appName
事件注解
注解 作用
@OnClick 点击事件
@OnCheckedChanged 选中,取消选中
@OnEditorAction 软键盘功能键
@OnFocusChange 焦点改变
@OnItemClick item 被点击(注意这里有坑,如果item里面有Button等这些有点击的控件事件的,需要设置这些控件属性focusable为false)
@OnItemLongClick item 长按(返回真可以拦截onItemClick)
@OnItemSelected item被选择事件
@OnLongClick 长按事件
@OnPageChange 页面改变事件
@OnTextChanged EditText里面的文字变化事件
@OnTouch 触摸事件
@Optional 选择性注入,如果当前对象不存在,就会抛出一个异常,为了压制这个异常,可以在变量或者方法上加入一下注解,让注入变成选择性的,如果目标View存在,则注入, 不存在,则什么事情都不做
代码混淆
-keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; }-keepclasseswithmembernames class * { @butterknife.* ; }-keepclasseswithmembernames class * { @butterknife.* ; }

插件 zelezny
将光标移到setContentView(R.layout.acty_login),将光标放到R.layout.acty_login,然后右键Generate,选择GenerateBUtterKnife Injections

    推荐阅读