首先添加点击事件注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnLongClick {
int[] value();
}
通过反射方式获取到带有此注解的Method
Class<? extends Activity> activityClass = activity.getClass();
Method[] declaredMethods = activityClass.getDeclaredMethods();
for (Method method : declaredMethods) {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if(annotationType.isAnnotationPresent(OnClick.class)){
View text = activity.findViewById(R.id.text);
text.setOnclickListener(()->{
method.invoke(activity);
});
}else if(annotationType.isAnnotationPresent(OnLongClick.class)){
...
}
}
}
新增一个修饰注解事件的类型注解,则获取方法时则可以动态代理view对应的事件
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventType {
Class listenerType();
String listenerSetter();
}
@EventType(listenerType = View.OnClickListener.class, listenerSetter = "setOnClickListener")
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value();
}
Class<? extends Annotation> annotationType = annotation.annotationType();
if (annotationType.isAnnotationPresent(EventType.class)) {
EventType eventType = annotationType.getAnnotation(EventType.class);
String listenerSetter = eventType.listenerSetter();
Class listenerType = eventType.listenerType();
Method value = annotationType.getDeclaredMethod("value");
int[] viewId = (int[]) value.invoke(annotation);
Object proxyInstance = Proxy.newProxyInstance(activity.getClassLoader(), new Class[]{listenerType}, new InvocationHandler() {
@Override
public Object invoke(Object o, Method mtd, Object[] objects) throws Throwable {
return method.invoke(activity, objects);
}
});
for (int id : viewId) {
View view = activity.findViewById(id);
Method setter = view.getClass().getMethod(listenerSetter, listenerType);
setter.invoke(view, proxyInstance);
}
}
具体使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtils.injectEvent(this);
}
@OnClick({R.id.text1, R.id.text2})
public void click(View view) {
switch (view.getId()) {
case R.id.text1:
Toast.makeText(this, "点击1", Toast.LENGTH_SHORT).show();
break;
case R.id.text2:
Toast.makeText(this, "点击2", Toast.LENGTH_SHORT).show();
break;
}
}