早就聽過Butter Knife這個神器,公司最近新開了一個專案,用到了這個框架,但也只是簡單使用自動繫結控制元件,昨天抽時間看了下官網,發現這個框架還可以做其他很多的工作,來提高開發效率,總結一下常用用法。
一 匯入
dependencies {
compile `com.jakewharton:butterknife:8.5.1`
annotationProcessor `com.jakewharton:butterknife-compiler:8.5.1`
}複製程式碼
目前最新版為8.5.1
二 用法
-
單個控制元件繫結
class ExampleActivity extends Activity { @BindView(R.id.title) TextView title;//@BindView註解加控制元件id標註要查詢的控制元件 @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);//在當前activity自動繫結 // TODO Use fields... } }複製程式碼
- 資源繫結
class ExampleActivity extends Activity { @BindString(R.string.title) String title;//@BindString註解加資源id標註要查詢的資源 @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 // ... }複製程式碼
-
根據自定義的根佈局來自動繫結佈局裡的控制元件
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);//自動繫結Activity根部局控制元件的時候直接傳this即可 // TODO Use fields... return view; } }複製程式碼
-
在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);//item佈局 holder = new ViewHolder(view);//傳給ViewHolder 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);//其實就是根據我們自己提供的根佈局來繫結控制元件 } } }複製程式碼
- 控制元件集合繫結
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name }) List<EditText> nameViews;複製程式碼
- 同時操作多個控制元件
ButterKnife.apply(nameViews, DISABLE); ButterKnife.apply(nameViews, ENABLED, false);複製程式碼
DISABLE,ENABLED是ButterKnife提供的一種資料型別ButterKnife.Action
,它是一個介面,需要我們根據需求實現其中的apply()方法,這裡: 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.apply具有多個過載方法,例如還可以設定屬性等:
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);複製程式碼
- 單個控制元件事件繫結
@OnClick(R.id.submit)//註解控制元件 public void test(View view) {//點選控制元件後觸發的方法,引數可選 // TODO submit data to server... }複製程式碼
- 多個控制元件事件繫結
@OnClick({ R.id.door1, R.id.door2, R.id.door3 }) public void test(View view) { switch(view.getId()){ case R.id.door1: //todo something break; case R.id.door2: //todo something break; case R.id.door3: //todo something break; default: break; } }複製程式碼
-
繫結重置
與Activity相比,Fragment的檢視具有不同的生命週期,在onCreateView中繫結檢視的時候,Butter Knife會返回一個Unbinder型別的物件,我們可以在合適的生命週期回撥方法中呼叫它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);//返回unbinder物件 // TODO Use fields... return view; } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind();//解除繫結 } }複製程式碼
-
可選繫結(OPTIONAL BINDINGS)
通常,控制元件繫結與事件繫結我們都需要,但是如果沒有找不到目標view的話會報錯,為了避免這種情況,可以用@Nullable和@Optional這兩個註解,如果找不到目標view存在,就自動繫結,不存在,也不會出錯。@Nullable @BindView(R.id.might_not_be_there) TextView mightNotBeThere; @Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() { // TODO ... }複製程式碼
- ButterKnife.findById()
Butter Knife提供了一個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);複製程式碼
findById()有兩個引數,第一個是目標view,有三種型別:View,Activity,Dialog,第二個引數是要查詢的控制元件id。它主要是通過返回泛型來自動執行型別轉換。
- 自動生成繫結的外掛
最後推薦一個外掛android butterknife zelezny,可以自動生成繫結程式碼:
具體用法請參考:blog.csdn.net/dreamliveme…
參考: