前言
從最初接觸的 ButterKnife 5.0 到后來的 ButterKnife 7.0 大改動辑莫,再到如今的 ButterKnife 8.4涧尿,ButterKnife也在不斷的進(jìn)步,相對于 ButterKnife 7.0 最新的 ButterKnife 8.4 也有不小的改進(jìn)茴厉,這樣本文就重點來介紹一下8.4 的使用。
ButterKnife 的添加依賴
ButterKnife 8.4 在編譯方面改用 annotationProcessor(編譯時注解)耻姥,這樣就需要我們手動添加編譯注解器。
-
首先,在Project的build.grade 中如圖添加:
-
接下來来农,在app的build.gradle中添加聲明,并引入依賴崇堰。
ButterKnife 的使用
ButterKnife 使用形式并沒有打的改動沃于,相對于Butterknife 7.0部分注解的名稱有做修改。
首先說一下不論是哪個版本的ButterKnife 都需要注意的幾個點:
- ButterKnife.bind(this); 的使用一定是在setContentView()之后的海诲;
- 不管注解的是對象還是函數(shù)方法都不能用private 或者 static 修飾繁莹,否則會報錯
- Activity中 綁定view
使用 @BindView 加上一個ID的形式 來注解,即可自動的映射出布局中的相對應(yīng)的View特幔。
class ExampleActivity extends Activity {
@BindView(R.id.title) TextView title;
@BindView(R.id.subtitle) TextView subtitle;
@BindView(R.id.footer) TextView footer;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}
- 資源綁定
使用@BindBool咨演,@BindColor,@BindDimen蚯斯,@BindDrawable薄风,@BindInt,@BindString綁定預(yù)定義的資源拍嵌,通過以下形式綁定到其相應(yīng)的字段遭赂。
class ExampleActivity extends Activity {
@BindString(R.string.title) String title;
@BindDrawable(R.drawable.graphic) Drawable graphic;
@BindColor(R.color.red) int red; // int or ColorStateList field
@BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
// ...
}
- 非Activity綁定
還可以通過提供自己的根視圖對任意對象執(zhí)行綁定(以下以Fragment為例)。
public class FancyFragment extends Fragment {
@BindView(R.id.button1) Button button1;
@BindView(R.id.button2) Button button2;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
}
同樣這種形式也可以應(yīng)用在Adapter 中横辆,簡化視圖的持有形式撇他。
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.whatever, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
}
holder.name.setText("John Doe");
// etc...
return view;
}
static class ViewHolder {
@BindView(R.id.title) TextView name;
@BindView(R.id.job_title) TextView jobTitle;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
- 多View綁定
- 將多個View 綁定到一個List 中 或者 數(shù)組也可以
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
-
apply方法,一次性對列表中的所有View執(zhí)行操作。
先來看一下apply方法都提供了那些重載:
不僅僅有對列表或數(shù)組的批量操作龄糊,還有對單個視圖的操作逆粹。
下面看一下具體使用:
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
//設(shè)置統(tǒng)一操作
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);
}
由上面實例可以看出,ButterKnife 提供了Action和Setter接口炫惩,允許指定簡單的行為僻弹;其次,Android Property 成員也可以與apply方法一起使用他嚷。
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
- 監(jiān)聽器綁定
- 監(jiān)聽器也可以自動配置到方法上,傳入的參數(shù)表示監(jiān)聽的對象蹋绽。
@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}
- 監(jiān)聽器方法的參數(shù)是可選的,即可以無需添加參數(shù)筋蓖。
@OnClick(R.id.submit)
public void submit() {
// TODO submit data to server...
}
- 定義一個特定的類型卸耘,它會自動轉(zhuǎn)換,需要注意的是粘咖,定義的參數(shù)必須是監(jiān)聽的對象或者其父類蚣抗,否則會轉(zhuǎn)換錯誤。
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
- 同樣瓮下,可以將一個方法配置給多個id,這里也有一點需要注意翰铡,傳入的參數(shù)必須要是各個監(jiān)聽對象共同的父類钝域。
@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();
}
}
- 自定義View可以通過不指定ID來綁定到自己的監(jiān)聽器。
public class FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
- 綁定解綁
** ButterKnife 8.4 相對于 ButterKnife 7.0 添加了解綁機(jī)制锭魔,要求Fragment在適當(dāng)?shù)臅r候進(jìn)行解綁例证。**
Fragment具有與Activity不同的生命周期。 當(dāng)在onCreateView中綁定Fragment時迷捧,需要在onDestroyView中將視圖設(shè)置為null织咧。 ButterKnife會在bind 時返回一個Unbinder實例。 在適當(dāng)?shù)纳芷诨卣{(diào)中調(diào)用其unbind方法漠秋。
public class FancyFragment 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);
// TODO Use fields...
return view;
}
@Override public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
- 可選性綁定
在使用過程中笙蒙,ButterKnife 還考慮到了 綁定時出現(xiàn)綁定目標(biāo)未找到的情況。默認(rèn)情況下膛堤,未找到會直接拋出異常手趣,如果需要避免拋出異常,ButterKnife也提供了結(jié)果方案肥荔,只需要 用 @Nullable 來注解 屬性绿渣,或者使用 @Optional來注解方法即可,使用如下燕耿。
@Nullable @BindView(R.id.might_not_be_there) TextView mightNotBeThere;
@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}
- ButterKnife.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);
-
其他監(jiān)聽器
ButterKnife 同時還提供了其他的監(jiān)聽器中符。
這里我們以 onItemSelected 為例:
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
// TODO ...
}
@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)
void onNothingSelected() {
// TODO ...
}
方法的參數(shù)是可選的,但同時需要符合 注解參數(shù)的要求誉帅,不能多參或者出現(xiàn)參數(shù)類型不存在的問題淀散,如果出現(xiàn)參數(shù)類型相同的情況,方法的參數(shù)會從左到右依次匹配蚜锨。
總結(jié):
本文例子 來源于 Butter Knife官網(wǎng)档插,文中的介紹也主要是根據(jù)官網(wǎng)給出的總結(jié),并且加入了個人在使用過程中的一些看法亚再,就算是一份學(xué)習(xí)筆記吧郭膛。