使用注解能够增加开发效率,但是可读性差,其他的注解框架有butterknife。
/**
* 注入View
*
*/
public static void injectView(Object target, ViewFinder viewFinder) {
if (target == null || viewFinder == null) {
throw new NullPointerException();
}
Class<?> cls = target.getClass();
while (cls != null && cls != Object.class && cls != Activity.class && cls != View.class) {
Field[] declaredFields = cls.getDeclaredFields();
for (Field field : declaredFields) {
if (!field.isAccessible())
field.setAccessible(true);
FindViewById findViewById = field.getAnnotation(FindViewById.class);
if (findViewById == null) {
continue;
} else {
int id = findViewById.value();
View view = viewFinder.findViewById(id);
if (view == null) {
// 根据注解的ViewID,无法查找到View, 检查控件在对应的XML中的ID是否存在
String msg = field.getName() + " 根据ID不能查找到对应的View,请检查XML资源文件中的id属性是否等于注解的ID";
throw new ViewInjectException(msg);
} else if (!field.getType().isInstance(view)) {
// 控件类型不匹配, 请检查XML中的控件类型和java代码类型是否匹配
String msg = field.getName() + " 类型匹配错误,java类型:" + field.getType().getSimpleName()
+ ", View在XML中申明的类型:" + view.getClass().getSimpleName() + ",请检查XML中的控件类型和java代码类型是否匹配";
throw new ViewInjectException(msg);
} else {
try {
field.set(target, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
cls = cls.getSuperclass();
}
}
/**
* 注入单击事件
*
*/
public static void injectOnClick(Object target, ViewFinder viewFinder) {
if (target == null || viewFinder == null) {
throw new NullPointerException();
}
Class<?> cls = target.getClass();
while (cls != null && cls != Object.class && cls != Activity.class && cls != View.class) {
Method[] methods = cls.getDeclaredMethods();
for (Method method : methods) {
if (!method.isAccessible()) {
method.setAccessible(true);
}
OnClick onClick = method.getAnnotation(OnClick.class);
if (onClick != null) {
Class<?>[] parameterTypes = method.getParameterTypes();
Class<?> viewClass = null;
if (parameterTypes.length != 1) {
String msg = method.getName() + " OnClick注解方法有且只能有一个参数!";
throw new ViewInjectException(msg);
} else {
viewClass = parameterTypes[0];
}
int[] ids = onClick.value();
for (int id : ids) {
View targetView = viewFinder.findViewById(id);
if (targetView == null) {
// 根据注解的ViewID,无法查找到对应的View, 检查控件在对应的XML中的ID是否存在
String msg = method.getName() + " 根据ID不能查找到对应的View,请检查XML资源文件中的id属性是否等于注解的ID";
throw new ViewInjectException(msg);
} else if (!viewClass.isAssignableFrom(targetView.getClass())) {
// 控件类型和方法参数不匹配, 请检查方法参数的类型
String msg = method.getName() + " 方法参数类型:" + viewClass.getName() + ", View在XML中申明的类型:"
+ targetView.getClass().getName();
throw new ViewInjectException(msg);
} else {
targetView.setOnClickListener(new InjectOnClickListener(method, target));
}
}
}
}
cls = cls.getSuperclass();
}
}