ButterKnife学习之—ButterKnife是怎么用的

ButterKnife学习之—ButterKnife是怎么用的

  • 前言
  • 为何要用ButterKnife
  • ButterKnife介绍
  • 简单示例
  • ButterKnife基本原理
  • 开始使用
    • 如何导入ButterKnife
    • 如何使用ButterKnife
      • 1、绑定
      • 2、各种注解方式
    • 代码混淆
    • 总结

前言

要成为一名优秀的Android开发者,除了丰富的项目经验外,还需要有一份完备的知识体系,在这里我们一起成长一起学习,让自己成为理想中的自己~

为何要用ButterKnife

在平常的Android开发中,是否会经常觉得当Layout中的控件比较多的时候要写一堆的findViewById()效率低下?是否觉得经常通过各种setxxxListener来设置事件监听很繁琐?那么ButterKnife就是解决以上问题的

ButterKnife介绍

  • ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象,有了ButterKnife可以很轻松的省去这些步骤。是大神JakeWharton的力作,目前使用很广。最重要的一点,使用ButterKnife对性能基本没有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class。项目集成起来也是特别方便,使用起来也是特别简单。
  • ButterKnife项目地址
  • ButterKnife的优势
    1、强大的View绑定和Click等各种事件处理功能,简化代码量,大大的提升了开发效率
    2、方便的处理Adapter里的ViewHolder绑定问题
    3、配置方便,不影响APP运行时效率
    4、增强代码可读性强

简单示例

public class MainActivity extends BaseActivity<MainContract.Presenter> implements MainContract.View {
	@BindView(R.id.test_tv)
	TextView testTv;
	@BindView(R.id.test_btn)
	Button testBtn;
    
    Unbinder unbinder;
	
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test_layout);
		unbinder = ButterKnife.bind(this, view);
	}
	
	@OnClick({R.id.test_tv,R.id.test_btn})
	protected void handleViewClick(View view){
		switch(view.getId()){
			case R.id.test_tv:
				Log.d("TEST","tsest tv click");
				break;
			case R.id.test_btn:
				Log.d("TEST","tsest btn click");
				break;
		}
	}

	@Override
	protected void onDestory(){
		super.onDestory();
		if (unbinder != null && unbinder != Unbinder.EMPTY) {
            unbinder.unbind();
            unbinder = null;
        }
	}
}

看到如上代码是不是觉得简洁很多了呀
通过示例代码可以看出,之前我们都是通过findViewById()的方法了找到xml布局中的View,这里我们使用了@BindView()的注解方式替代了。然后使用了@OnClick()替代了之前的setOnClickListener()方法。当然ButterKnife类似的方法还有很多,我们后续会逐一介绍。

ButterKnife基本原理

ButterKnife的初期版本是通过使用注解+反射这样的运行时解析的方式实现上述功能的,之后为了改善性能,便使用了注解+APT编译时解析技术并从中生成配套模板代码的方式来实现。所以在开始使用之前,我们先简单的了解下什么是APT。
APT是Annotation Processing Tool的缩写,即注解处理工具。
它的使用步骤一般是这样的:

  • 首先声明注解的声明周期为CLASS,即@Retention(CLASS)
  • 然后通过集成AbstractProcessor自定义一个注解处理器。
  • 在编译的时候,编译器会扫描所有带有你要处理的注解的类,最后再调用AbstractProcessor的process方法,对注解进行处理

开始使用

激动人心的时候到了,现在我们来学习怎么用ButterKnife

如何导入ButterKnife

首先,需要在module的build.gradle中,添加如下:

android {
  ...
  // Butterknife requires Java 8.
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  implementation 'com.jakewharton:butterknife:10.2.1'
  annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
}

如何使用ButterKnife

1、绑定

首先要将ButterKnife与Activity、Fragment或者View先进行绑定。由于每次在Activity或者Fragment中进行绑定,所以这里建议将bind的操作写到BaseActivity或BaseFragment中,这样之后都继承他们,就不用再重复的写bind代码了
注意:绑定Activity必须在setContentView之后

public abstract class BaseActivity extends Activity {

    private Unbinder unbinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getContentView());
        unbinder = ButterKnife.bind(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (unbinder != null && unbinder != Unbinder.EMPTY) {
            unbinder.unbind();
            unbinder = null;
        }
    }

    protected abstract int getContentView();
}

在8.4版本开始ButterKnife移除了ButterKnife.unBind()方法,当时取而代之的是ButterKnife.bind(this)会返回一个Unbinder的引用,通过Unbinder的unbind()方法进行解除绑定。

2、各种注解方式

  • 控件的注解@BindView
// 这里的修饰类不能是private或者static,否则会报异常: @BindView fields must not be private or static.
@BindView(R.id.test_tv)
protected TextView testTv;
  • 多个控件的注解@BindViews
@BindViews({R.id.test_tv,R.id.test_tv2})
protected List<TextView> testTvs;
  • 字符串的注解@BindString
@BindString(R.string.test_str)
protected String mTestStr;
  • 字符串数组的注解@BindArray
@BindArray(R.array.test_str_array)
protected String[] testStrArray;
  • Bitmap资源的注解@BindBitmap
@BindBitmap(R.mipmap.ic_launcher)
protected Bitmap bitmap;
  • 点击事件绑定@OnClick(类似的还有@OnTouch等)

注意:这类事件绑定的可以不用声明View,直接注解在方法上进行绑定

单个View的点击事件绑定

@OnClick(R.id.test_tv)
protected void handleViewClick(){
	Log.d("TEST","test tv click");
}

多个View的点击事件

@OnClick({R.id.test_tv,R.id.test_tv2})
protected void handleMoreViewClick(View view){
	int viewId = view.getId();
	switch(viewId){
		case R.id.test_tv:
			Log.d("TEST","test tv click");
			break;
		case R.id.test_tv2:
			Log.d("TEST","test tv2 click");
			break;
	}
}
  • 给EditText添加输入回调监听
    在给EditText添加输入回调监听的时候,需要指定回调的类型,参考如下代码
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)  
void beforeTextChanged(CharSequence s, int start, int count, int after) {  

}  
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)  
void onTextChanged(CharSequence s, int start, int before, int count) {  

}  
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)  
void afterTextChanged(Editable s) {  

}  

代码混淆

-keep class butterknife.** { *; }  
-dontwarn butterknife.internal.**  
-keep class **$$ViewBinder { *; }  

-keepclasseswithmembernames class * {  
    @butterknife.* <fields>;  
}  

-keepclasseswithmembernames class * {  
    @butterknife.* <methods>;  
}  


总结

最后这里做个小小的总结
1、ButterKnife.bind()的调用在Activity中必须在setContentView之后
2、声明修饰符不能用private和static,否则会抛异常
3、建议封装一个自己的BaseActivity或BaseFragment来统一调用ButterKnife.bind()方法,子类继承后则可不用再进行绑定
4、在8.4之后版本移除了unBInd方法,使用ButterKnife.bind(this)返回一个Unbinder的引用,通过Unbinder的unbind()方法来进行解绑

最后完成后,在Review下自己的代码是不是觉得清晰了很多呢?
什么?还是觉得麻烦?有没有更好的办法呢?还可以更懒吗?别急下一篇我们来聊聊怎么用插件生成以上代码!

你可能感兴趣的:(ButterKnife,android,移动开发)