ButterKnife 使用总结

一、前言

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

优势:

  1. 强大的View绑定和click事件处理功能,简化代码,提高开发效率
  2. 方便处理Adapter里的ViewHolder绑定问题
  3. 运行是不会影响App效率,使用配置方便
  4. 代码清晰,可读性强

二、基本配置

步骤

  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 = 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

你可能感兴趣的:(ButterKnife 使用总结)