Android 中利用註解來實現findViewById

一般狀況下,咱們在寫控件的時候都會調用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

相關文章
相關標籤/搜索