目錄
-
- 1. 什麼是ButterKnife?
- 2. 在android studio中配置ButterKnife
-
- 2.1 配置ButterKnife8.8.1
- 2.2 配置ButterKnife10
- 2.3 踩坑一:The Android Gradle plugin supports only Butterknife Gradle plugin version 9.0.0-rc2 and higher
- 2.4 踩坑二:Annotation processors must be explicitly declared now
- 3. 如何使用ButterKnife?
- 4. ButterKnife自動生成插件Zelezny安裝
1. 什麼是ButterKnife?
ButterKnife是一個專注于Android系統View、Resource、Action的注入架構,可以減少大量的findViewById以及setOnClickListener代碼,并且可以利用一個叫做Zelezny的插件,可視化一鍵生成。
媽媽再也不用擔心我敲代碼敲到手抽筋兒了~
2. 在android studio中配置ButterKnife
2.1 配置ButterKnife8.8.1
- 在project的build.gradle中添加:
classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
添加後示例如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
// butterknife8.8.1
classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
- 在app的build.gradle中添加:
apply plugin: 'com.jakewharton.butterknife'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
添加後示例如下:
apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.butterknife'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "fxjzzyo.com.butterknifetestdemo"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
// butterknife
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}
注意 什麼時候用ButterKnife8呢?當你使用Android support相容庫時,就是那個
com.android.support:support-v4
或者
com.android.support:support-v7
.
2.2 配置ButterKnife10
- 在project的build.gradle中添加:
classpath 'com.jakewharton:butterknife-gradle-plugin:10.0.0'
添加後示例如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.jakewharton:butterknife-gradle-plugin:10.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
- 在app的build.gradle中添加:
apply plugin: 'com.jakewharton.butterknife'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
implementation 'com.jakewharton:butterknife:10.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'
添加後示例如下:
apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.butterknife'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "fxjzzyo.com.butterknifetestdemo"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
// 視圖綁定跨架構butterknife10
implementation 'com.jakewharton:butterknife:10.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'
}
注意!!! 什麼時候用ButterKnife10呢?當你使用AndroidX相容庫時,就是那個
androidx.appcompat:appcompat:xxx
.
如果你引入這個ButterKnife10版本,發現以下錯誤:
Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:36:5-364:19 to override.
那麼恭喜你,AndroidX和Android support包沖突了。你的項目依賴的是Android support庫,而
ButterKnife10内部使用AndroidX開發,ButterKnife8内部使用的是Android support。是以,
解決方法是:乖乖的使用ButterKnife8吧您嘞~
2.3 踩坑一:The Android Gradle plugin supports only Butterknife Gradle plugin version 9.0.0-rc2 and higher
當你的Gradle plugin或者Android studio版本較高時,會發現butterknife8死活下載下傳不下來,崩潰~
那麼就可能是下面這個錯了:
ERROR: The Android Gradle plugin supports only Butterknife Gradle plugin version 9.0.0-rc2 and higher.
The following dependencies do not satisfy the required version:
root project 'MyProject' -> com.jakewharton:butterknife-gradle-plugin:8.8.1
Affected Modules: app
就是說目前你的Gradle plugin僅支援butterknife9.0.0-rc2以及更高版本了,而到了butterknife10就是使用AndroidX庫的了,如果你的工程還是使用Android support又想使用butterknife,那麼隻能用butterknife9.0.0-rc2這個版本。
配置方法與8.8.1一樣,就是把8.8.1替換成9.0.0-rc2即可。
2.4 踩坑二:Annotation processors must be explicitly declared now
當你遇到坑一,按解決方法替換成9.0.0-rc2後,可能會遇到以下錯誤:
Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor. Please add them to the annotationProcessor configuration.
- auto-value-1.5.2.jar (com.google.auto.value:auto-value:1.5.2)
Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior. Note that this option is deprecated and will be removed in the future.
See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.
-
解決方法一:
build.gradle(app)檔案的dependencies裡添加下面依賴即可。
-
解決方法二:
按錯誤提示,在build.gradle(app)檔案的defaultConfig裡添加:
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
這裡推薦方法一。
3. 如何使用ButterKnife?
注:以下的所有操作都要在綁定了目前Activity( ButterKnife.bind(this);)的前提下才能進行!
1) 綁定view @BindView(R.id.xxx)
package fxjzzyo.com.butterknifetestdemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
public class MainActivity extends AppCompatActivity {
//綁定
@BindView(R.id.tv_hello)
TextView tvHello;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//首先要綁定activity!!!
ButterKnife.bind(this);
//使用綁定後的view
tvHello.setText("hahahahahah");
}
}
2) 綁定views @BindViews({ R.id.button1 , R.id.button2 , R.id.button3 })
//綁定
@BindViews({ R.id.button1 , R.id.button2 , R.id.button3 })
public List<Button> buttonList ;
3) 綁定點選事件@OnClick( )
@OnClick(R.id.button1 ) //給 button1 設定一個點選事件
public void showToast(){
Toast.makeText(this, "is a click",Toast.LENGTH_SHORT).show();
}
4) 綁定長按點選事件@OnLongClick( )
@OnLongClick( R.id.button1 ) //給 button1 設定一個長按事件
public boolean showToast2(){
Toast.makeText(this, "is a long click", Toast.LENGTH_SHORT).show();
return true ;
}
5) 多個控件綁定同一個事件
/**
* 兩個不同的button都相應onButterKnifeBtnClick事件回調
* @param button
*/
@OnClick({R.id.btn_butter_knife, R.id.btn_butter_knife1})
public void onButterKnifeBtnClick(Button button) {
Log.i(TAG, "onButterKnifeBtnClick");
}
自定義的控件不通過ID也可以綁定到自己的事件
public class FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
6) 多事件回調
比如EditText添加addTextChangedListener,使用前:
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
使用後:
@OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
void onTextChanged(CharSequence s, int start, int before, int count) {
}
@OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterTextChanged(Editable s) {
}
7) 綁定資源檔案
//綁定string字元串
@BindString(R.string.title_btn_butter_knife)
String butterKnifeStr;
//綁定Drawable圖檔
@BindDrawable(R.mipmap.ic_launcher)
Drawable butterKnifeDrawable;
//綁定Bitmap圖檔
@BindBitmap(R.mipmap.ic_launcher)
Bitmap butterKnifeBitmap;
//綁定數組
@BindArray(R.array.day_of_week)
String weeks[];
//綁定color顔色
@BindColor(R.color.colorPrimary)
int colorPrimary;
//綁定Dimen尺寸
@BindDimen(R.dimen.activity_horizontal_margin)
Float spacer;
8) 在Fragment中使用
由于不同的視圖生命周期,是以需要在onCreateView中 bind,在onDestroyView中 unbind
public class MyFragment extends Fragment {
@BindView(R.id.button1) Button button1;
@BindView(R.id.button2) Button button2;
private Unbinder unbinder;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
//綁定
unbinder = ButterKnife.bind(this, view);
return view;
}
@Override public void onDestroyView() {
super.onDestroyView();
//解綁
unbinder.unbind();
}
}
9) 在ViewHolder中使用
public class MyAdapter extends BaseAdapter {
@Override public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
} else {
view = inflater.inflate(R.layout.mylayout, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
}
holder.name.setText("fxjzzyo");
return view;
}
static class ViewHolder {
@BindView(R.id.title) TextView name;
@BindView(R.id.job_title) TextView title;
public ViewHolder(View view) {
//綁定ViewHolder
ButterKnife.bind(this, view);
}
}
}
10)ButterKnife.findById()
ButterKnife 也提供了findById函數,通過findById()可以擷取Activity、Dialog、View中的view,并且是泛型類型不需要強轉。
View view =LayoutInflater.from(context).inflate(R.layout.layout, null);
TextView firstName = ButterKnife.findById(view, R.id.first_name);
TextView lastName = ButterKnife.findById(view, R.id.last_name);
ImageView photo = ButterKnife.findById(view, R.id.photo);
4. ButterKnife自動生成插件Zelezny安裝
在android studio的setting中,如下圖:
安裝後,會提示重新開機android studio,重新開機即可
接下來就能自動生成綁定了~~
就是這麼讓你一懶再懶~~
生成方法:
将光标放到Activity、Fragment、或ViewHolder中的資源檔案上,右鍵—>Generate—Generate ButterKnife Injections
大概如下圖:
自己勾勾選選,就明白怎麼用了。
文章參考:
http://write.blog.csdn.net/mdeditor#!postId=78440509
http://www.cnblogs.com/whoislcj/p/5620128.html
完結,撒花~