IOC註解框架

IOC註解框架

  1. Butter Knife
  2. ViewUtils(Xutils)

02-ViewUtils的實現

  1. MainActivity.java

public class MainActivity extends Activity {
  private String name;
  @ViewInject(R.id.tv1)
  private TextView tv1;
  //因爲在ViewInject註解中的變量爲value,則註解中可以省略value值
  @ViewInject(R.id.tv2)
  private TextView tv2;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ViewUtils.inject(this);
  }
  @Deprecated
  @OnClick(R.id.btn1)
  public void clickXXX(View view){
    Log.d("tag", "tv1="+tv1+"\ntv2="+tv2);

    Toast.makeText(this, "我被點擊了", Toast.LENGTH_SHORT).show();
  }
}
  1. ViewInject.java

//便是該註解是屬性值
@Target(ElementType.FIELD)
//表示啊該註解在內存中也生效
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
  public int value();
}
  1. 按鈕點擊註解OnClick.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnClick {
  public int value();
}
  1. ViewUtils.java

public class ViewUtils {
  public static void inject(Activity activity) {
    bindView(activity);// 綁定控件
    bindOnClick(activity);// 綁定點擊事件
  }

  private static void bindView(Activity activity) {
     // 1. 獲取字節碼
    Class clazz = activity.getClass();
     // 2. 獲取所有的字段
    Field[] declaredFields = clazz.getDeclaredFields();
    // 3. 遍歷字段,只過濾出添加了@ViewInject的字段
    for (Field field : declaredFields) {
      // 4. 獲取到字段之後,獲取字段的註解對象
      ViewInject viewInject = field.getAnnotation(ViewInject.class);
      // 如果該字段上有註解就代表這個字段就是用戶想綁定View的
      if (viewInject != null) {
        // 5. 獲取自定義註解上面的id
        int resId = viewInject.value();
        // 6.通過 View view = Activity.findViewByid(id)
        View view = activity.findViewById(resId);
        // 7. 通過暴力反射將view設置該當前字段
        field.setAccessible(true);
        try {
          field.set(activity, view);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
  private static void bindOnClick(final Activity activity) {
    //1. 獲取字節碼
    Class clazz = activity.getClass();
    //2. 獲取所有的Method
    Method[] declaredMethods = clazz.getDeclaredMethods();
     //3. 遍歷方法,只找有自定義註解的方法
    for (final Method method : declaredMethods) {
       //4. 獲取當前Method上面的註解
      OnClick onClick = method.getAnnotation(OnClick.class);
      if (onClick != null) {
         //5. 獲取到註解上的id
        int resId = onClick.value();
        //6. 通過 View btn = Activity.findViewByid(id)
        final View view = activity.findViewById(resId);
        /*
         * 7. 給btn綁定點擊監聽事件 btn.setOnClickListener(new OnClickListener(){
         * public void onClick(View view){ 8. 通過暴力反射調用當前遍歷到的Method } });
         */
        view.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            // 8. 通過暴力反射調用當前遍歷到的Method
            method.setAccessible(true);
            try {
             method.invoke(activity, view);
            } catch (Exception e) {
             e.printStackTrace();
            }
          }
        });
      }
    }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章