一般狀況下,咱們在寫控件的時候都會調用findViewById的方法來獲取View實例,而且還要強制轉換(Android studio 3.0以後不須要),很是繁瑣,固然了市面上也有ButterKinfe這樣的的第三方庫來輔助開發者提升開發效率,若是咱們本身去實現這樣的框架其實也很簡單,幾個步驟就能夠完成,不過首先要對註解有比較深入的理解。框架
第一步:定義註解this
代碼以下:spa
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface LcsBindView { int value(); }
主要來講定義註解分三步,@inteface標明當前是註解類,@號不能漏掉,不然變成了接口了指針
@Target註解對象
咱們註解做用的目標,這裏是ElementType.FIELD,也就是做用於字段的,還有其餘的修飾以下:接口
1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述字段
3.LOCAL_VARIABLE:用於描述局部變量
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述參數
7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明開發
@Retention註解get
註解的運行級別it
RetentionPolicy的類型有如下幾種io
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在運行時有效(即運行時保留)
看解釋應該明白,他們的級別是:1<=2<=3
至此註解就定義完成了。
第二步驟:綁定關聯
顧名思義,簡單的定義是使用不了的,咱們要把控件和註解關聯起來,才能正常使用
線上代碼:
//核心方法 public static void bindViews(Activity activity) { Class<? extends Activity> activityClass = activity.getClass();//獲取activity的class Field[] fields = activityClass.getDeclaredFields();//獲取activity的字段 //遍歷全部的字段 for (Field field : fields) { //獲取該字段的註解 LcsBindView lcsBindView = field.getAnnotation(LcsBindView.class); //!=null 說明該字段有註解而且是指定的註解 if (lcsBindView != null) { //獲取到註解總傳入的數值value int viewId = lcsBindView.value(); if(viewId != -1){ try { //獲取到activity中findViewById的方法 Method findViewByIdMethod = activityClass.getMethod("findViewById", int.class); try { //執行findViewById方法 Object resView = findViewByIdMethod.invoke(activity, viewId); //容許經過反射訪問私有變量 field.setAccessible(true); //把字段的值設置該view的實例 field.set(activity, resView); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } } } } }
先看裏面的註釋,大概能夠理解咱們的關聯步驟,主要是先獲取到activity的class實例,以後在獲取到類中的全部字段,以後再進行遍歷、獲取字段的註解類,若是是當前咱們須要的註解類,咱們再獲取到activity中的findViewById的方法,經過反射去執行這個方法,而且把獲取到value也就是控件Id傳進去,那麼咱們的控件就被實例化了,而後再把返回的object的對象設置到該對應字段上面,這樣在activity中用此字段就不會發生空指針了,整個過程就結束了,activity中的使用以下:
@LcsBindView(R.id.tv_test) private TextView tvTest;
BindViewUtils.bindViews(this); tvTest.setText("我是經過 @LcsBindView 找到的,哈哈哈~");
先進行註解修飾,再進行註解關聯,就可使用了,是否是很簡單呢:D