1. butterknife 9.0接入
1.1 常规项目(非library)接入
在app的build.gradle引用butterknife:
implementation 'com.jakewharton:butterknife:9.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0'
1.2 library项目接入:
1.2.1 在项目根目录build.grdle添加:
buildscript {
repositories {
...
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
}
}
1.2.2 在library的build.gradle添加:
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
...
dependencies {
...
implementation 'com.jakewharton:butterknife:9.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0'
}
2. butterknife基本用法:
2.1 绑定View
@BindView(R.id.tv_test1)
TextView tvTest1;
2.2 绑定多个View
@BindViews({R.id.tv_test2, R.id.tv_test2})
public List<TextView> textList;
2.3 绑定string
@BindString(R.string.base_bind_string)
String str;
2.4 绑定Bitmap
@BindBitmap(R.drawable.ic_launcher)
public Bitmap mBitmap ;
2.5 绑定颜色
@BindColor(R.color.base_bind_color)
int color;
2.6.绑定点击事件
@OnClick(R2.id.btn_test1)
public void showToast(){
...
}
2.7 绑定长按事件
@OnLongClick(R2.id.btn_test1)
public boolean showToastl(){
...
return true;
}
3 在Activity中使用:
public class BaseActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
ButterKnife.bind(this);
}
}
在activity使用注意事项:
1. activity中调用ButterKnife.bind(this)必须在setContentView之后,且不需要做解绑操作
2. 使用ButterKnife修饰的元素(例如@BindView修饰)访问控制权限不能是static或者private
4. 在Fragment中使用:
public class BaseFragment extends Fragment {
private Unbinder unbinder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View contentView = onCreateViewEx(inflater, container, savedInstanceState);
unbinder = ButterKnife.bind(this, contentView);
return contentView;
}
/**
* onDestroyView中进行解绑操作
*/
@Override
public void onDestroyView() {
super.onDestroyView();
if(unbinder != null) {
unbinder.unbind();
unbinder = null;
}
}
}
在Fragment使用注意事项:
1.在fragment中使用ButterKnife.bind(this,view)绑定,this不能替换成getActivity()
2.在fragment中使用ButterKnife需要进行解绑操作,一般在onDestroyView调用unbind()方法
5 ViewHolder使用
public static class ViewHolder extends RecyclerView.ViewHolder{
@BindView(R2.id.tv_item)
public TextView mTextView;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
5 注意问题:
1 绑定多个控件@BindViews里面不能有重复ID,否则报错:
错误: @BindViews annotation contains duplicate ID 2131165346. (com.cold.butterknifedemo.BaseActivity.textList)
2 长按事件处理方法需要有返回值,否则报错:
错误: @OnLongClick methods must have a 'boolean' return type. (com.cold.butterknifedemo.BaseActivity.showToastl)
3 在有继承层级的类中使用butterknife,如果使用的类都在同一个模块里,则直接使用就可以了,如果不在同一个library中,会导致生成的ViewBinding不会调用父类的ViewBinding,解决方法是在子类动态调用父类ViewBiding的构造函数。
https://github.com/JakeWharton/butterknife/issues/808
6 报错及异常解决:
错误1:
Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Failed to transform file 'classes.jar' to match attributes {artifactType=android-dex, dexing-is-debuggable=true, dexing-min-sdk=15} using transform DexingTransform
> Error while dexing.
butterknife 9.0.0 使用了 java 8
在app的builid.gradle文件添加:
android {
...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
...
}
弹出警告:
WARNING: API 'variantOutput.getProcessResources()' is obsolete and has been replaced with 'variantOutput.getProcessResourcesProvider()'.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance.
To determine what is calling variantOutput.getProcessResources(), use -Pandroid.debug.obsoleteApi=true on the command line to display a stack trace.
Affected Modules: module1
这是gradle-4.10.1-all的一个bug,使用gradle-4.6-all即可
解决方案:
gradle插件使用3.2.1,在根目录build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
...
}
gradle-wrapper.properties修改:
...
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
错误3:
在我的项目中集成了databinding,导致butterknife使用不当报错会只想databinding,给排查异常带来了很大的困扰。
例如,变量使用private, static修饰,变量类型和获取的实际类型不对应等。
demo