1.首先看下我们需要的效果:
@OnclickInject(R.id.button)
public void clickButton(View view) {
switch (view.getId()) {
case R.id.button:
Toast.makeText(this, "点击了", Toast.LENGTH_SHORT).show();
break;
}
}
这里省去了我们常用的SetOnClickListener(new View.OnClickListener…);而是通过直接注解的方式@OnclickInject(R.id.button)来实现点击事件;
2.写事件注解:
//注解目标:ElementType.ANNOTATION_TYPE 指注解类型
@Target(ElementType.ANNOTATION_TYPE)
//保存策略:RetentionPolicy.RUNTIME 运行时
@Retention(RetentionPolicy.RUNTIME)
//注解类 @interface 关键词
public @interface EventInJect {
//这三个都是事件参数
Class<?> listenerType();
String listenerSetter();
String methodName();
}
3.写事件注解之下的注解,方法注解
//注解目标:ElementType.METHOD 指注解方法
@Target(ElementType.METHOD)
//保存策略:RetentionPolicy.RUNTIME 运行时
@Retention(RetentionPolicy.RUNTIME)
//注意:注解之上的注解,事件注解需要传递三个参数
第一个参数:事件的参数,一个内部class类 例如:View.OnClickListener.clas
第二个参数:事件的名称,调用的方法 例如:setOnClickListener
第三个参数:事件内部类的方法名, 例如:onClick
@EventInJect(listenerType = View.OnClickListener.class, listenerSetter = "setOnClickListener", methodName = "onClick")
public @interface OnclickInject {
//所有ViewId的数组集合;
int[] value();
}
- 通过注解反射的方式,实现事件的注入
/**
* 事件的注入
*/
public static void viewOnclickInJect(Activity activity) {
Class<? extends Activity> aClass = activity.getClass();
Method[] methods = aClass.getMethods();
//遍历所有的方法
for (Method method : methods) {
Annotation[] annotations = method.getAnnotations();
//遍历每一个方法上的注解
for (Annotation annotation : annotations) {
//获取注解的类型
Class<? extends Annotation> annotationType = annotation.annotationType();
//根据注解类型获取注解
EventInJect eventInJect = annotationType.getAnnotation(EventInJect.class);
if (eventInJect != null) {
//获取监听器的名称,监听器的类型,调用的方法
String listenerSetter = eventInJect.listenerSetter();
Class<?> listenerType = eventInJect.listenerType();
String methodName = eventInJect.methodName();
try {
//拿到OnclickInject注解中的value方法
Method aMethod = annotationType.getDeclaredMethod("value");
//获取所有的View的id
int[] viewIds = (int[]) aMethod.invoke(annotation);
//通过InvocationHandler设置代理
//注意:这里请结合Java动态代理理解
DynamicHandler handler = new DynamicHandler(activity);
handler.addMethod(methodName, method);
Object newProxyInstance = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class<?>[]{listenerType}, handler);
//遍历所有view,设置事件
for (int viewId : viewIds) {
View view = activity.findViewById(viewId);
Method viewMethod = view.getClass().getMethod(listenerSetter, listenerType);
viewMethod.invoke(view, newProxyInstance);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
此处只是个人的学习记录,如果想了解学习请看大神的博客:http://blog.youkuaiyun.com/lmj623565791/article/details/39269193;