寫在前面:該文檔使用7.0版本援雇,8.0版本方法名有所改動(dòng)曙旭,建議看官方文檔钻趋,整體業(yè)務(wù)邏輯和原理沒什么變動(dòng)蛮位,官網(wǎng)
在Android編程過程中,我們會(huì)寫大量的布局和點(diǎn)擊事件萄焦,像初始view鹦蠕、設(shè)置view監(jiān)聽這樣簡(jiǎn)單而重復(fù)的操作讓人覺得麻煩類钟病,所以可以采用注解的方式去實(shí)現(xiàn),而ButterKnife則是注解中相對(duì)簡(jiǎn)單易懂的很不錯(cuò)的開源框架辖所,而網(wǎng)上的文檔和例子都過時(shí)了,7.0之后的版本改動(dòng)很大,之前的注解都不能用了您觉,所以借鑒官方文檔總結(jié)了一下,接下來就介紹一下如何使用在孝。基本參照官方文檔仔燕,加上自己的心得五辽。
ButterKnife 優(yōu)勢(shì):
1.強(qiáng)大的View綁定和Click事件處理功能俄周,簡(jiǎn)化代碼,提升開發(fā)效率
2.方便的處理Adapter里的ViewHolder綁定問題
3.運(yùn)行時(shí)不會(huì)影響APP效率,使用配置方便
4.代碼清晰橄维,可讀性強(qiáng)
使用心得:
1.Activity ButterKnife.bind(this);必須在setContentView();之后,且父類bind綁定后竞川,子類不需要再bind
2.Fragment ButterKnife.bind(this, mRootView);
3.屬性布局不能用private or static 修飾床牧,否則會(huì)報(bào)錯(cuò)
4.setContentView()不能通過注解實(shí)現(xiàn)。(其他的有些注解框架可以)
官網(wǎng)http://jakewharton.github.io/butterknife/
使用步驟:
一.導(dǎo)入ButterKnife jar包:
1)如果你是Eclipse,可以去官網(wǎng)下載jar包
2)如果你是AndroidStudio可以直接 File->Project Structure->Dependencies->Library dependency 搜索butterknife即可,第一個(gè)就是
3)當(dāng)然也可以用maven和gradle配置
[html]view plaincopy
MAVEN
com.jakewharton
butterknife
(insert?latest?version)
GRADLE
compile?'com.jakewharton:butterknife:(insert?latest?version)'
Be?sure?to?suppress?this?lint?warning?in?your?build.gradle.(關(guān)閉)
lintOptions?{
disable?'InvalidPackage'
}
注意如果在Library 項(xiàng)目中使用要按如下步驟(github中有具體描述)否則無法找到view:
注:官網(wǎng)和github也有對(duì)應(yīng)的引用步驟。
二.常見使用方法:
1)由于每次都要在Activity中的onCreate綁定Activity暂吉,所以個(gè)人建議寫一個(gè)BaseActivity完成綁定阎肝,子類繼承即可
注:ButterKnife.bind(this)嫉父;綁定Activity 必須在setContentView之后:
實(shí)現(xiàn)如下(FragmentActivity 實(shí)現(xiàn)一樣):
[java]view plaincopy
publicabstractclassBaseActivityextendsActivity?{
publicabstractintgetContentViewId();
@Override
protectedvoidonCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
ButterKnife.bind(this);
initAllMembersView(savedInstanceState);
}
protectedabstractvoidinitAllMembersView(Bundle?savedInstanceState);
@Override
protectedvoidonDestroy()?{
super.onDestroy();
ButterKnife.unbind(this);//解除綁定,官方文檔只對(duì)fragment做了解綁
}
}
2)綁定fragment
[java]view plaincopy
publicabstractclassBaseFragmentextendsFragment?{
publicabstractintgetContentViewId();
protectedContext?context;
protectedView?mRootView;
@Nullable
@Override
publicView?onCreateView(LayoutInflater?inflater,@NullableViewGroup?container,@NullableBundle?savedInstanceState)?{
mRootView?=inflater.inflate(getContentViewId(),container,false);
ButterKnife.bind(this,mRootView);//綁定framgent
this.context?=?getActivity();
initAllMembersView(savedInstanceState);
returnmRootView;
}
protectedabstractvoidinitAllMembersView(Bundle?savedInstanceState);
@Override
publicvoidonDestroyView()?{
super.onDestroyView();
ButterKnife.unbind(this);//解綁
}
}
3)綁定view
[java]view plaincopy
@Bind(R.id.hello_world)
TextView?mHelloWorldTextView;
@Bind(R.id.app_name)
TextView?mAppNameTextView;//view
4)綁定資源
[java]view plaincopy
@BindString(R.string.app_name)
String?appName;//sting
@BindColor(R.color.red)
inttextColor;//顏色
@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 綁定
[java]view plaincopy
publicclassTestAdapterextendsBaseAdapter?{
privateList?list;
privateContext?context;
publicTestAdapter(Context?context,?List?list)?{
this.list?=?list;
this.context?=?context;
}
@Override
publicintgetCount()?{
returnlist==null?0:?list.size();
}
@Override
publicObject?getItem(intposition)?{
returnlist.get(position);
}
@Override
publiclonggetItemId(intposition)?{
returnposition;
}
@Override
publicView?getView(intposition,?View?convertView,?ViewGroup?parent)?{
ViewHolder?holder;
if(convertView?==null)?{
convertView?=?LayoutInflater.from(context).inflate(R.layout.layout_list_item,null);
holder?=newViewHolder(convertView);
convertView.setTag(holder);
}else{
holder?=?(ViewHolder)?convertView.getTag();
}
holder.textview.setText("item====="+?position);
returnconvertView;
}
staticclassViewHolder?{
@Bind(R.id.hello_world)
TextView?textview;
publicViewHolder(View?view)?{
ButterKnife.bind(this,?view);
}
}
}
6)點(diǎn)擊事件的綁定:不用聲明view,不用setOnClickLisener()就可以綁定點(diǎn)擊事件
a.直接綁定一個(gè)方法
[java]view plaincopy
@OnClick(R.id.submit)
publicvoidsubmit(View?view)?{
//?TODO?submit?data?to?server...
}
b.所有監(jiān)聽方法的參數(shù)是可選的
[java]view plaincopy
@OnClick(R.id.submit)
publicvoidsubmit()?{
//?TODO?submit?data?to?server...
}
c.定義一個(gè)特定類型,它將自動(dòng)被轉(zhuǎn)換
[java]view plaincopy
@OnClick(R.id.submit)
publicvoidsayHi(Button?button)?{
button.setText("Hello!");
}
d.多個(gè)view統(tǒng)一處理同一個(gè)點(diǎn)擊事件蹦玫,很方便,避免抽方法重復(fù)調(diào)用的麻煩
[java]view plaincopy
@OnClick({?R.id.door1,?R.id.door2,?R.id.door3?})
publicvoidpickDoor(DoorView?door)?{
if(door.hasPrizeBehind())?{
Toast.makeText(this,"You?win!",?LENGTH_SHORT).show();
}else{
Toast.makeText(this,"Try?again",?LENGTH_SHORT).show();
}
}
e.自定義view可以綁定自己的監(jiān)聽,不指定id
[java]view plaincopy
publicclassFancyButtonextendsButton?{
@OnClick
publicvoidonClick()?{
//?TODO?do?something!
}
}
f.給EditText加addTextChangedListener(即添加多回調(diào)方法的監(jiān)聽的使用方法)绢馍,利用指定回調(diào)舰涌,實(shí)現(xiàn)想回調(diào)的方法即可,哪個(gè)注解不會(huì)用點(diǎn)進(jìn)去看下源碼上的注釋就會(huì)用了
[java]view plaincopy
@OnTextChanged(value?=?R.id.mobileEditText,?callback?=?OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
voidbeforeTextChanged(CharSequence?s,intstart,intcount,intafter)?{
}
@OnTextChanged(value?=?R.id.mobileEditText,?callback?=?OnTextChanged.Callback.TEXT_CHANGED)
voidonTextChanged(CharSequence?s,intstart,intbefore,intcount)?{
}
@OnTextChanged(value?=?R.id.mobileEditText,?callback?=?OnTextChanged.Callback.AFTER_TEXT_CHANGED)
voidafterTextChanged(Editable?s)?{
}
7)對(duì)一組View進(jìn)行統(tǒng)一操作
a.裝入一個(gè)list
[java]view plaincopy
@Bind({?R.id.first_name,?R.id.middle_name,?R.id.last_name?})
List?nameViews;
b.設(shè)置統(tǒng)一處理
[java]view plaincopy
staticfinalButterKnife.Action?DISABLE?=newButterKnife.Action()?{
@Overridepublicvoidapply(View?view,intindex)?{
view.setEnabled(false);
}
};
staticfinalButterKnife.Setter?ENABLED?=newButterKnife.Setter()?{
@Overridepublicvoidset(View?view,?Boolean?value,intindex)?{
view.setEnabled(value);
}
};
c.統(tǒng)一操作處理宇弛,例如設(shè)置是否可點(diǎn)彻况,屬性等
[java]view plaincopy
ButterKnife.apply(nameViews,?DISABLE);
ButterKnife.apply(nameViews,?ENABLED,false);
8)可選綁定:默認(rèn)情況下纽甘,“綁定”和“監(jiān)聽”綁定都是必需的。如果不能找到目標(biāo)視圖泽裳,則將拋出異常胸囱。所以做空處理
[java]view plaincopy
@Nullable@Bind(R.id.might_not_be_there)?TextView?mightNotBeThere;
@Nullable@OnClick(R.id.maybe_missing)voidonMaybeMissingClicked()?{
//?TODO?...
}
三、代碼混淆
[java]view plaincopy
-keepclassbutterknife.**?{?*;?}
-dontwarn?butterknife.internal.**
-keepclass**$$ViewBinder?{?*;?}
-keepclasseswithmembernamesclass*?{
@butterknife.*?;
}
-keepclasseswithmembernamesclass*?{
@butterknife.*?;
}
四谤职、Zelezny插件的使用
在AndroidStudio->File->Settings->Plugins->搜索Zelezny下載添加就行 允蜈,可以快速生成對(duì)應(yīng)組件的實(shí)例對(duì)象蒿柳,不用手動(dòng)寫。使用時(shí)妓蛮,在要導(dǎo)入注解的Activity 或 Fragment 或 ViewHolder的layout資源代碼上圾叼,右鍵——>Generate——Generate ButterKnife Injections,然后就出現(xiàn)如圖的選擇框构挤。(此動(dòng)態(tài)圖來自官網(wǎng))