好了,言歸正傳。
這一篇文章,我們不談ButterKnife的基本使用,只談如何通過(guò)JavaSe的技術(shù),思考并分析ButterKnife這一Android開(kāi)發(fā)界內(nèi)排行前十的注解框架。
唯物主義辯證法認(rèn)為,世界上一切事物都是具有普遍的聯(lián)系。我們首先從ButterKnife的使用步驟開(kāi)始,倒推分析該框架使用了什么樣的技術(shù),然后自己寫一個(gè)簡(jiǎn)單的ButterKnife小框架。
在正式寫這篇博客之前,需要對(duì)反射以及注解(JavaSe技術(shù))有一個(gè)初步的認(rèn)識(shí),就算不了解的也沒(méi)有關(guān)系,筆者也提供了兩篇博客供大家學(xué)習(xí)參考,點(diǎn)擊這里了解反射,點(diǎn)擊這里了解注解?,(這兩篇也是筆者一字一字碼出來(lái)的,望各位大兄弟不吝star)只需要花個(gè)十多分鐘認(rèn)真細(xì)心的看,反射和注解都不是很大的問(wèn)題。接下來(lái)的東西還是很需要這兩篇博客中使用到的基礎(chǔ)。
說(shuō)起B(yǎng)utterKnife(黃油刀),大家肯定會(huì)想到,哇,這個(gè)是用來(lái)簡(jiǎn)化findViewById以及快速實(shí)現(xiàn)點(diǎn)擊事件等等一個(gè)深受大家好評(píng)的框架、沒(méi)錯(cuò),下圖就是大家熟悉的寫法

熟悉注解的同學(xué),可能一眼就看出,咦,這個(gè)@BindView以及@OnClick不就是兩個(gè)注解嗎?沒(méi)錯(cuò),的確是,而且,這個(gè)注解的類型是int值,因?yàn)槔锩媸蔷唧w的View ID。了解這種情況后,就有了如下代碼:首先,我們先寫找控件的注解

步驟1:
在使用ButterKnife注解之前,我們需要bind(Activty),
所以,我們就按照那種寫法,先聲明一個(gè)ButterKnife類,里面有個(gè)bind方法,參數(shù)是Activty
步驟2:
A:既然從外部傳入了這個(gè)Activity,那么,我們就可以通過(guò)暴力反射獲取該Activity上所有的成員變量,這里返回的是字段數(shù)組,
B:(因?yàn)槭菙?shù)組,所以需通過(guò)迭代器遍歷獲取每一個(gè)字段) 拿到成員變量之后,繼續(xù)通過(guò)暴力反射其變量上的自定義注解 ?就 ?可以獲取注解上的值(核心邏輯)
C:接著,我們既然通過(guò)B步驟已經(jīng)獲取到注解上的值(也就是控件的ID),那么就可以通過(guò)findViewByid去獲取具體的View控件
D:最后,在通過(guò)反射將C步驟獲取到的控件, 將其控件賦值給變量


最后,為了測(cè)試這種寫法能否達(dá)到預(yù)期的效果,我寫了一個(gè)Demo,經(jīng)測(cè)試,效果如圖:


經(jīng)測(cè)試,myTextViewOne,myTextViewTwo這兩個(gè)控件,我沒(méi)有findViewById, 依舊可以獲取到TextView上的值,所以,這個(gè)小功能經(jīng)測(cè)試是可行的,
類似的,還有一個(gè)自定義注解點(diǎn)擊事件,
依舊可以按照上面的寫法,先寫一個(gè)OnClick的自定義注解,如下圖

這里需要注意的是,
我們的點(diǎn)擊事件的邏輯,是寫在方法上的,所以,需要定義注解的使用范圍是在方法上 也就是 @Target(ElementType.METHOD)
接下來(lái)的步驟,和上面的bindview 步驟差不多,
(暴力反射---獲取注解的值----通過(guò)該值找到控件---對(duì)控件進(jìn)行點(diǎn)擊監(jiān)聽(tīng)---反射調(diào)用使用了注解的方法),
這里直接上圖

接下來(lái),我們寫代碼測(cè)試該注解:

經(jīng)測(cè)試,這個(gè)功能是完全可以使用的,
這樣,一個(gè)簡(jiǎn)單而不簡(jiǎn)約的迷你型ButterKnife框架就寫好了。
最后總結(jié):
1:自定義注解綁定的是具體的控件,也就是int值,根據(jù)自定義注解去定義這個(gè)int屬性值
2:在使用了該自定義注解后的控件,通過(guò)暴力反射獲取字段在根據(jù)其字段拿到具體的注解屬性值
3:根據(jù)拿到具體的屬性值,在做進(jìn)一步的操作
4:當(dāng)然,要是做到真正的ButterKnife框架還是有一些差距。但是我們這里只做簡(jiǎn)單的技術(shù)分析
最后,千里之行、始于足下,加油!
源碼,(直接看圖就可以了吧)附github地址
如果這篇文章對(duì)您有開(kāi)發(fā)or學(xué)習(xí)上的些許幫助,希望各位看官留下寶貴的star,謝謝。
Ps:著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)注明作者, 商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處(開(kāi)頭或結(jié)尾請(qǐng)?zhí)砑愚D(zhuǎn)載出處,添加原文url地址),文章請(qǐng)勿濫用,也希望大家尊重筆者的勞動(dòng)成果,謝謝。