IOC註解框架
- Butter Knife
- ViewUtils(Xutils)
02-ViewUtils的實現
- 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();
}
}
- ViewInject.java
//便是該註解是屬性值
@Target(ElementType.FIELD)
//表示啊該註解在內存中也生效
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
public int value();
}
- 按鈕點擊註解OnClick.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnClick {
public int value();
}
- 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();
}
}
});
}
}
}
}