寫作原因:程序員喜歡偷懶坚踩,對于安卓程序員來說,把時(shí)間花在不用動(dòng)腦筋的findViewById()上簡直讓人難以忍受韭邓。此外大量的點(diǎn)擊監(jiān)聽事件的分散化使得代碼可讀性下降澎埠。于是虽缕,基于注解的ButterKnife應(yīng)運(yùn)而生。
參考鏈接:
ButterKnife官網(wǎng):http://jakewharton.github.io/butterknife/
ButterKnife GitHub地址:https://github.com/JakeWharton/butterknife
ButterKnife-Zelezny地址:https://github.com/avast/android-butterknife-zelezny
簡介
先來看看ButterKnife有哪些功能吧蒲稳,官網(wǎng)上是這樣描述的:
- 通過使用@BindView來消除調(diào)用findViewById()氮趋;
- 可以把多個(gè)View放在一個(gè)數(shù)組或者list中。然后一次性可以同時(shí)對這些View的動(dòng)作江耀,屬性等進(jìn)行操作凭峡;
- 通過使用@OnClick注解來消除由監(jiān)聽器帶來的匿名內(nèi)部類;
- 通過對resource進(jìn)行注解來消除多余的資源查找代碼决记。
獲取ButterKnife:
- 在你的項(xiàng)目的build.gradle中加入以下依賴:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
- 在你的Module的build.gradle中加入以下依賴:
apply plugin: 'android-apt'
android {
...
}
dependencies {
compile 'com.jakewharton:butterknife:8.1.0'
apt 'com.jakewharton:butterknife-compiler:8.1.0'
}
注意:apply plugin: 'android-apt'
基本使用
下面的代碼演示了ButterKnife的基本使用技巧:
class ExampleActivity extends Activity {
@BindView(R.id.user) EditText username;
@BindView(R.id.pass) EditText password;
@BindString(R.string.login_error) String loginErrorMessage;
@OnClick(R.id.submit) void submit() {
// TODO call server...
}
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}
包括以下幾個(gè)步驟:
1.定義UnBinder對象,對待操作元素進(jìn)行注解:
定義:private UnBinder unBinder;
對View:@BindView(R.id.user) EditText username;
對Resource:@BindString(R.string.login_error) String loginErrorMessage;
(注:資源綁定有以下注解:@BindBool, @BindColor, @BindDimen, @BindDrawable, @BindInt, @BindString)
對監(jiān)聽事件:
@OnClick(R.id.submit) void submit() {
// TODO call server...
}
2.在onCreate方法或者onCreateView方法中調(diào)用方法:
unBinder = ButterKnife.bind(this);//如果在Fragment中使用ButterKnife.bind(this,view);
3.在onDestory方法或者onDestoryView中解除綁定:
unBinder = ButterKnife.unbind();
進(jìn)階操作:
1.利用ViewList實(shí)現(xiàn)同時(shí)配置多個(gè)View:
①. 將多個(gè)View綁定到一個(gè)List中:
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
②. 調(diào)用ButterKnife.apply()方法:
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
按照官網(wǎng)的思路倍踪,上面三行分別是對nameViews中所有View的action系宫,Setter和Property的設(shè)置索昂,但是僅僅調(diào)用了apply()方法并不能真正修改nameViews中的View,必須完成下一步工作扩借。
③. 實(shí)現(xiàn)接口:
static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
@Override public void apply(View view, int index) {
view.setEnabled(false);
}
};
static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
@Override public void set(View view, Boolean value, int index) {
view.setEnabled(value);
}
};
上面代碼已經(jīng)將action和Setter實(shí)現(xiàn)椒惨,重寫接口內(nèi)部方法apply或set,在內(nèi)部實(shí)現(xiàn)對nameViews的操作潮罪。這樣就完成了同時(shí)操作多個(gè)View的功能康谆。
2. 利用形參直接對當(dāng)前View進(jìn)行操作
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
3. 實(shí)現(xiàn)多View點(diǎn)擊事件的關(guān)聯(lián)(原理同2)
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
if (door.hasPrizeBehind()) {
Toast.makeText(this, "You win!", LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Try again", LENGTH_SHORT).show();
}
}
4.防止目標(biāo)View不存在出現(xiàn)exception的請況的發(fā)生
@Nullable @BindView(R.id.might_not_be_there) TextView mightNotBeThere;
@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}
通過使用@Nullable或者@Optional實(shí)現(xiàn)防止因?yàn)槟繕?biāo)View不存在出現(xiàn)exception的請況的發(fā)生。
5. 代替onItemClickListener的注解實(shí)現(xiàn)
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
// TODO ...
}
6. 通過LayoutInflater獲取View的ButterKnife實(shí)現(xiàn)方法findById:
View view = LayoutInflater.from(context).inflate(R.layout.thing, 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);
注:這個(gè)真沒覺得哪里簡單了嫉到。沃暗。。
到此我們講完了ButterKnife的基本使用何恶。怎樣不錯(cuò)吧孽锥?下面有更強(qiáng)大的東西——ButterKnifeZelezny,配合著這個(gè)神器一起使用细层,可以為我們的項(xiàng)目節(jié)省大量時(shí)間和增加代碼可讀性惜辑。
ButterKnifeZelezny
下載地址:
http://plugins.jetbrains.com/plugin/7369
關(guān)于AS安裝插件的問題在這里不多闡述了,不會(huì)的自行百度疫赎。
基本用法
下面這幅圖展示了ButterKnifeZelezny的基本用法盛撑。

基本步驟:
- 有所使用的布局 ID 上點(diǎn)擊右鍵 (例如上圖中的 R.layout.activity_settings ), 然后選擇 Generate -> Generate ButterKnife Injections
- 在對話框中選擇需要注入的 View捧搞, 還有個(gè)選項(xiàng)可以給 Adapter 創(chuàng)建一個(gè) ViewHolder抵卫。
- 點(diǎn)擊 Confirm , 代碼自動(dòng)生成实牡!
總結(jié):
本文只是關(guān)于ButterKnife用法的介紹陌僵,關(guān)于Java中的依賴注解的知識(shí)博主仍在學(xué)習(xí)中,有興趣參照《Java編程思想》一書關(guān)于Annotation的介紹创坞,此外歡迎繼續(xù)關(guān)注博主的Square全家桶系列碗短。