天天看點

Android ButterKnife學習總結

目錄

    • 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

  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
}

           
  1. 在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

  1. 在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
}

           
  1. 在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 ButterKnife學習總結

安裝後,會提示重新開機android studio,重新開機即可

接下來就能自動生成綁定了~~

就是這麼讓你一懶再懶~~

生成方法:

将光标放到Activity、Fragment、或ViewHolder中的資源檔案上,右鍵—>Generate—Generate ButterKnife Injections

大概如下圖:

Android ButterKnife學習總結

自己勾勾選選,就明白怎麼用了。

文章參考:

http://write.blog.csdn.net/mdeditor#!postId=78440509

http://www.cnblogs.com/whoislcj/p/5620128.html

完結,撒花~