實現注入view,簡單案例剖析butterknife原理
ButterKnife注入框架我相信大家都用過至少聽過吧,它的出現簡直是android開發人員的一大福利,徹底解放了無止境的findViewById,而是通過優雅的註解來實現view的賦值,如果你真沒聽過那我在這裡只能貼上一張github的截圖,自己好好反思吧~
1w5的star你還有什麼不學的理由!!!
好的,今天我們不說butterfnife怎麼用,而是仿照框架中的實現原理,用最簡單的例子自己來實現view的注入!
1、編寫自定義註解類
既然是注入的形式對view賦值,那麼當然少不了註解,我們最常用的莫過於setContentView和findViewById,我們先來定義這兩個註解(註釋中順便幫同學們補一些註解的知識):
setContentView
/**
* @Target描述註解的使用範圍
* 1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述區域性變數
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述引數
7.TYPE:用於描述類、介面(包括註解型別) 或enum宣告
*/
@Target(ElementType.TYPE)
/**
* @Retention 該Annotation被保留的時間長短
* 1.SOURCE:在原始檔中有效(即原始檔保留)
2.CLASS:在class檔案中有效(即class保留)
3.RUNTIME:在執行時有效(即執行時保留)
*/
@Retention(RetentionPolicy.CLASS)
public @interface SetContent {
int value() default -1;
}
findViewById
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
int value();
}
註解定義好之後,我們的目標是在activity中這樣使用對不對
@SetContent(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv_text)
private TextView textView;
}
這是我們需要一個解析器。
2、編寫註解解析器,為這些view賦值
/**
* Created by admin on 2017/4/2.
* 注入解析器
* 單例
*/
public class MyAnnotationInject {
private static MyAnnotationInject INSTANCE;
private List<Object> mInjectObjs = new ArrayList<Object>();
public static MyAnnotationInject init() {
if (INSTANCE == null) {
INSTANCE = new MyAnnotationInject();
}
return INSTANCE;
}
/**
* 註冊需要注入的類物件
* @param injectObj
*/
public void regist(@NonNull Object injectObj) {
if(mInjectObjs.contains(injectObj)){
return;
}
if (injectObj instanceof Activity) {
Activity activity = (Activity) injectObj;
//拿到注入的class物件
Class<Activity> clz = (Class<Activity>) activity.getClass();
try {
injectContentView(activity, clz);
injectView(activity, clz);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
mInjectObjs.add(injectObj);
}
/**
* 注入view
*/
private void injectView(Activity activity, Class<Activity> clz) throws IllegalAccessException {
//獲得所有的屬性,包括public、protected、private
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
//遍歷所有屬性,找到標有Bindview註解的屬性
if (field.isAnnotationPresent(BindView.class)) {
//拿到BindView註解的值
BindView annotation = field.getAnnotation(BindView.class);
int viewId = annotation.value();
//如果是私有屬性,修改屬性賦值之前必須加可修改許可權
field.setAccessible(true);
//給屬性重新賦值,引數1:要修改的屬性的物件 , 引數2 : 新值
field.set(activity, activity.findViewById(viewId));
}
}
}
/**
* 注入activity佈局
*/
private void injectContentView(Activity activity, Class<Activity> clz) {
if (clz.isAnnotationPresent(SetContent.class)) {
//拿到SetContent註解的值
SetContent annotation = clz.getAnnotation(SetContent.class);
int resId = annotation.value();
if (resId != -1) {
activity.setContentView(resId);
}
}
}
/**
* 登出需要注入的類物件
* @param injectObj
*/
public void unRegist(Object injectObj) {
if (mInjectObjs.contains(injectObj))
mInjectObjs.remove(injectObj);
}
}
3、Activity中使用我們的註解來代替findViewById
@SetContent(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv_text)
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyAnnotationInject.init().regist(this);
textView.setText("通過註解注入view成功!");
}
@Override
protected void onDestroy() {
super.onDestroy();
MyAnnotationInject.init().unRegist(this);
}
}
我們看一下效果:
當然我這只是butterknife中冰山一角,如果想要具體學習整個框架可以去學習butterknife的原始碼~
butterKnife地址,點我
相關推薦
實現注入view,簡單案例剖析butterknife原理
ButterKnife注入框架我相信大家都用過至少聽過吧,它的出現簡直是android開發人員的一大福利,徹底解放了無止境的findViewById,而是通過優雅的註解來實現view的賦值,如果你真沒聽過那我在這裡只能貼上一張github的截圖,自己好好反思吧~
python實現DES加密,簡單案例
環境:python3.6 庫:pyDes from pyDes import des, CBC, PAD_PKCS5 import binascii # 祕鑰 KEY='mHAxsLYz' def
python實現RSA加密,簡單案例
環境:python3.6 第三方庫:M2Crypto 這個庫windows上很難裝,linux上直接用pip install 首先獲取一對祕鑰,具體生產祕鑰方式百度上有線上工具。 然後將生成
使用 vue 實現拖拽的簡單案例,不會超出可視區域
實現拖拽之前,先了解幾個小常識: 這兩種獲取滑鼠座標的方法,區別在於基於的物件不同: pageX和pageY獲取的是滑鼠指標距離文件(HTML)的左上角距離,不會隨著滾動條滾動而改變; clientX和clientY獲取的是滑鼠指標距離可視視窗(不包括上面的位址列和滑動條)的距離
Mybatis實現Mapper介面的簡單案例
用了很久mybatis,一直猜想mybatis是使用動態代理的方式實現mapper介面的,通過實踐探索之後,果然如此,但是還是遇到了不少問題,在此粘出來供初學者參考。 首先我將案例程式碼粘出來,這段程式碼簡單實現了從service層開始呼叫mapper介面的過程
MATLAB實現FCM演算法,簡單程式碼實現
先來看看結果好了,這是一幅原圖,經過FCM演算法之後,假設選擇3個center,將這幅彩色影象轉化後得到一個只有三種灰度值的影象,還能將每一種灰度單獨提取出來,得到對應的只含有一種灰度的三個圖。 它的數學原理為 這裡Vk取v1,v2,v3三個任意初始值
JAVA實現排列組合,簡單的一比
/** * 思路: * 遞迴,第一層把迴圈把n個數中的第i個裝入結果的第一個位置 * 把剩下的n-2個數迴圈裝入第二個位置 * 把剩下的n-3個數迴圈裝入第三個位置 * .....
壓縮稀疏矩陣以及使用三元組實現矩陣乘法,簡單易懂
思路:既然使用三元組去實現,所以首先要定義一個三元組 typedef struct node { int row, col, v;//分別代表行數,列數,以及元素的值,整個式子表示在原矩陣的第row行,第col列,有一個值為v的數 } node;
DNS域名系統,簡單描述其工作原理。
DNS域名系統:當DNS客戶機需要在程式中使用名稱時,它會查詢DNS伺服器來解析該名稱。客戶機發送的每條查詢資訊包括三條資訊:包括:指定的DNS域名,指定的查詢型別,DNS域名的指定類別。基於UDP服務,埠53. 該應用
C語言實現printf函式,即引數可變函式原理
我們在C語言程式設計中會遇到一些引數個數可變的函式,例如printf() 這個函式,它的定義是這樣的: int printf( const char* format, ...); 它除了有一個引數format固定以外,後面跟的引數的個數和型別是 可變的,例如我們可以有以下不
Android之---ButterKnife-View注入框架(簡單介紹和在Studio中安裝)
ButterKnife-View注入框架(簡單介紹和在Studio中安裝) 1.簡單介紹 Butter Knife使用簡單介紹 作為一名Android開發,是不是經常厭煩了大量的findViewById以及setOnClickListener程式碼,而
c#實現簡單的注入容器,認識注入容器的基本原理
在學習了反射和注入的概念後,加上專案中也用到 比如 AutoFuc 還有 unity 等容器。就有點想寫自己的容器的想法。 然後 搜尋了下 注入容器相關的文章,大多是多某個成熟的注入容器的程式碼進行解析,或者是對 注入概念的解析。成熟的框架考慮到方方面面,原始碼對於新手來說
Kotlin編譯時註解,簡單實現ButterKnife
ButterKnife在之前的Android開發中還是比較熱門的工具,幫助Android開發者減少程式碼編寫,而且看起來更加的舒適,於是簡單實現一下ButterKnife,相信把下面的程式碼都搞懂,看ButterKnife的難度就小很多。 今天實現的是編譯時註解,其實執行時註解也一樣能實現ButterKnif
自己定義View時,用到Paint Canvas的一些溫故,簡單的幀動畫(動畫一 ,"掏糞男孩Gif"順便再提提onWindowFocusChanged)
eat android 內容 rri generated 簡單的 fadein spl onclick 轉載請註明出處:王亟亟的大牛之路 之前在繪畫的過程中提到了靜態的旋轉啊,縮放啊,平移等一些效果。那麽自己定義的View當然也有動態的效果也就是我們的
Android 簡單案例:繼承BaseAdapter實現Adapter
for ack import apt ret bsp position hang layout import android.view.LayoutInflater; import android.view.View; import android.view.ViewGr
Android 簡單案例:可移動的View
bool fst boolean store import cup tcl etc last CrossCompatibility.rar 1. VersionedGestureDetector.java import android.content.Context; i
簡單實現頂部固定,中部自適應布局
col position fix enter span text auto pos otto 最近在重構web導航的時候就發現一個問題,如何實現頂部固定,中部自適應的布局。 很多人會認為這很簡單啊,頂部使用position: fixed;就可
用心剖析,詳解如何搭建百萬PV網站架構,簡單易懂!!!
socket cache sad nco sla tom 百萬 redis主從 debug 簡介: 本項目案例結合SVN、LNMP和MySQL三種環境,部署一個社交網站,本社交網站采用PHP語言開發,搭建SVN服務器進行版本控制和集中管理PHP程序員開發的代碼,以Nginx
C#實現軟體授權,限定MAC執行(軟體license管理,簡單軟體註冊機制)
最近做了一個綠色免安裝軟體,領導臨時要求加個註冊機制,不能讓現場工程師隨意複製。事出突然,只能在現場開發(離開現場軟體就不受我們控了)。花了不到兩個小時實現了簡單的註冊機制,稍作整理。 基本原理:1.軟體一執行就把計算機的CPU、主機板、BIOS、MAC地址記錄下來,然後加密(key=key1)生成
一個小小的 Shell 管道符,內部實現可真不簡單!
管道命令我們經常使用,將一個指令的輸出匯入另一個指令的輸入,也就是屁股對上嘴,這個原理連程式設計小學生都知道。但是如果要深入問進去,一個指令的輸出是如何匯入到另一個指令的輸入,管道又起到什麼角色,估計能回答這個問題的人不足 1%。下面我們來深入分析一下管道指令的實現原理,對於下面的這條指令,shell 到底幹