標籤:
ButterKnife 是View注入架構,不會偷懶的程式員不是好程式員。
class ExampleActivity extends Activity { TextView title; TextView subtitle; TextView footer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); title = (TextView) findViewById(R.id.title); subtitle = (TextView) findViewById(R.id.subtitle); footer = (TextView) findViewById(R.id.footer); // TODO Use views... }}
而用ButterKnife之後的代碼是這樣的:
class ExampleActivity extends Activity { @InjectView(R.id.title) TextView title; @InjectView(R.id.subtitle) TextView subtitle; @InjectView(R.id.footer) TextView footer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.inject(this);
// TODO Use "injected" views... }}
在Activity 中注入
class ExampleActivity extends Activity { @InjectView(R.id.title) TextView title; @InjectView(R.id.subtitle) TextView subtitle; @InjectView(R.id.footer) TextView footer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.inject(this); // TODO Use "injected" views... }}
在 Fragment 中注入
public class FancyFragment extends Fragment { @InjectView(R.id.button1) Button button1; @InjectView(R.id.button2) Button button2; @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fancy_fragment, container, false); ButterKnife.inject(this, view); // TODO Use "injected" views... return view; }}
在 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.whatever, parent, false); holder = new ViewHolder(view); view.setTag(holder); } holder.name.setText("John Doe"); // etc... return convertView; } static class ViewHolder { @InjectView(R.id.title) TextView name; @InjectView(R.id.job_title) TextView jobTitle; public ViewHolder(View view) { ButterKnife.inject(this, view); } }}
注入回呼函數
下面是幾種注入回呼函數的方法樣本:
// 帶有 Button 參數@OnClick(R.id.submit)public void sayHi(Button button) { button.setText("Hello!");} // 不帶參數@OnClick(R.id.submit)public void submit() { // TODO submit data to server...} // 同時注入多個 View 事件@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(); }}
Reset函數
如果需要在 介面 銷毀的時候,把注入的 View 設定為 Null, 則可以用 reset 函數:
public class FancyFragment extends Fragment { @InjectView(R.id.button1) Button button1; @InjectView(R.id.button2) Button button2; @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fancy_fragment, container, false); ButterKnife.inject(this, view); // TODO Use "injected" views... return view; } @Override void onDestroyView() { super.onDestroyView(); Views.reset(this); }}
另外 還支援 可選的 View 注入,如果該 View 沒有,就沒有吧:
@Optional @InjectView(R.id.might_not_be_there) TextView mightNotBeThere; @Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() { // TODO ...}
還有兩個 findViewById 函數來簡化尋找 View 的方式,如果上面都滿足不了你的需求,你可以用用他們:
View view = LayoutInflater.from(context).inflate(R.layout.thing, null);TextView firstName = Views.findById(view, R.id.first_name);TextView lastName = Views.findById(view, R.id.last_name);ImageView photo = Views.findById(view, R.id.photo);
最後,如果你是用Android Studio來作為IDE的話,那麼有一個ButterKnife的外掛程式android-butterknife-zelezny, 該外掛程式可以讓你手動產生上述注入代碼,從此讓自己成為一個更懶惰的程式員,上張吧。
Android-- ButterKnife