寫在前面:該文檔使用7.0版本,8.0版本方法名有所改動,建議看官方文檔,整體業務邏輯和原理沒什麼變動;
在Android程式設計過程中,我們會寫大量的布局和點選事件,像初始view、設定view監聽這樣簡單而重複的操作讓人覺得麻煩類,是以可以采用注解的方式去實作,而ButterKnife則是注解中相對簡單易懂的很不錯的開源架構,而網上的文檔和例子都過時了,7.0之後的版本改動很大,之前的注解都不能用了,是以借鑒官方文檔總結了一下,接下來就介紹一下如何使用。基本參照官方文檔,加上自己的心得。
ButterKnife 優勢:
1.強大的View綁定和Click事件處理功能,簡化代碼,提升開發效率
2.友善的處理Adapter裡的ViewHolder綁定問題
3.運作時不會影響APP效率,使用配置友善
4.代碼清晰,可讀性強
使用心得:
1.Activity ------ ButterKnife.bind(this);必須在setContentView();之後,且父類bind綁定後,子類不需要再bind
2.Fragment ------ ButterKnife.bind(this, mRootView);
3.屬性布局不能用private or static 修飾,否則會報錯
4.setContentView()不能通過注解實作。(其他的有些注解架構可以)
官網 http://jakewharton.github.io/butterknife/
使用步驟:
一.導入ButterKnife jar包:
1)如果你是Eclipse,可以去官網下載下傳jar包
2)如果你是AndroidStudio可以直接 File->Project Structure->Dependencies->Library dependency 搜尋butterknife即可,第一個就是
3)當然也可以用maven和gradle配置
MAVEN
<dependency>
<groupId>com.jakewharton</groupId>
<artifactId>butterknife</artifactId>
<version>(insert latest version)</version>
</dependency>
GRADLE
compile 'com.jakewharton:butterknife:(insert latest version)'
Be sure to suppress this lint warning in your build.gradle.(關閉)
lintOptions {
disable 'InvalidPackage'
}
注意如果在Library 項目中使用要按如下步驟(github中有具體描述)否則無法找到view:
注:官網和github也有對應的引用步驟。
二.常見使用方法:
1)由于每次都要在Activity中的onCreate綁定Activity,是以個人建議寫一個BaseActivity完成綁定,子類繼承即可
注:ButterKnife.bind(this);綁定Activity 必須在setContentView之後:
實作如下(FragmentActivity 實作一樣):
public abstract class BaseActivity extends Activity {
public abstract int getContentViewId();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
ButterKnife.bind(this);
initAllMembersView(savedInstanceState);
}
protected abstract void initAllMembersView(Bundle savedInstanceState);
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);//解除綁定,官方文檔隻對fragment做了解綁
}
}
2)綁定fragment
public abstract class BaseFragment extends Fragment {
public abstract int getContentViewId();
protected Context context;
protected View mRootView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRootView =inflater.inflate(getContentViewId(),container,false);
ButterKnife.bind(this,mRootView);//綁定framgent
this.context = getActivity();
initAllMembersView(savedInstanceState);
return mRootView;
}
protected abstract void initAllMembersView(Bundle savedInstanceState);
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);//解綁
}
}
3)綁定view
@Bind(R.id.hello_world)
TextView mHelloWorldTextView;
@Bind(R.id.app_name)
TextView mAppNameTextView;//view
4)綁定資源
@BindString(R.string.app_name)
String appName;//sting
@BindColor(R.color.red)
int textColor;//顔色
@BindDrawable(R.mipmap.ic_launcher)
Drawable drawable;//drawble
@Bind(R.id.imageview)
ImageView mImageView;
@Bind(R.id.checkbox)
CheckBox mCheckBox;
@BindDrawable(R.drawable.selector_image)
Drawable selector;
5)Adapter ViewHolder 綁定
public class TestAdapter extends BaseAdapter {
private List<String> list;
private Context context;
public TestAdapter(Context context, List<String> list) {
this.list = list;
this.context = context;
}
@Override
public int getCount() {
return list==null ? 0 : list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.layout_list_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText("item=====" + position);
return convertView;
}
static class ViewHolder {
@Bind(R.id.hello_world)
TextView textview;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
6)點選事件的綁定:不用聲明view,不用setOnClickLisener()就可以綁定點選事件
a.直接綁定一個方法
@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}
b.所有監聽方法的參數是可選的
@OnClick(R.id.submit)
public void submit() {
// TODO submit data to server...
}
c.定義一個特定類型,它将自動被轉換
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
d.多個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();
}
}
例子二:
@OnClick({ R.id.tv_text1, R.id.tv_text2, R.id.tv_text3, R.id.tv_text4 })
public void sayHi(Button button) { //控件根據你所綁定的控件而定
switch (button.getId()) {
case R.id.tv_text1:
button.setText("你按到我了啦1!");
Toast.makeText(this, "你按到我了啦1!", Toast.LENGTH_SHORT).show();
break;
case R.id.tv_text2:
button.setText("你按到我了啦2!");
Toast.makeText(this, "你按到我了啦2!", Toast.LENGTH_SHORT).show();
break;
case R.id.tv_text3:
button.setText("你按到我了啦3!");
Toast.makeText(this, "你按到我了啦3!", Toast.LENGTH_SHORT).show();
break;
case R.id.tv_text4:
button.setText("你按到我了啦4!");
Toast.makeText(this, "你按到我了啦4!", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
e.自定義view可以綁定自己的監聽,不指定id
public class FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
f.給EditText加addTextChangedListener(即添加多回調方法的監聽的使用方法),利用指定回調,實作想回調的方法即可,哪個注解不會用點進去看下源碼上的注釋就會用了
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
void onTextChanged(CharSequence s, int start, int before, int count) {
}
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterTextChanged(Editable s) {
}
7)對一組View進行統一操作
a.裝入一個list
@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
b.設定統一處理
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);
}
};
c.統一操作處理,例如設定是否可點,屬性等
[java] view plain copy
- ButterKnife.apply(nameViews, DISABLE);
- ButterKnife.apply(nameViews, ENABLED, false);
8)可選綁定:預設情況下,“綁定”和“監聽”綁定都是必需的。如果不能找到目标視圖,則将抛出異常。是以做空處理 [java] view plain copy
- @Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;
- @Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
- // TODO ...
- }
三、代碼混淆
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
四、Zelezny插件的使用
在AndroidStudio->File->Settings->Plugins->搜尋Zelezny下載下傳添加就行 ,可以快速生成對應元件的執行個體對象,不用手動寫。使用時,在要導入注解的Activity 或 Fragment 或 ViewHolder的layout資源代碼上,右鍵——>Generate——Generate ButterKnife Injections,然後就出現如圖的選擇框。(此動态圖來自官網)
轉載 http://blog.csdn.net/itjianghuxiaoxiong/article/details/50177549