1、定义事件类型注解
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventType {
Class listenerType();
String listenerSetter();
}
2、点击注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@EventType(listenerType = View.OnClickListener.class, listenerSetter = "setOnClickListener")
public @interface OnClick {
int[] value();
}
3、长按注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@EventType(listenerType = View.OnLongClickListener.class, listenerSetter = "setOnLongClickListener")
public @interface OnLongClick {
int[] value();
}
4、工具类
package com.enjoy.reflect;
import android.app.Activity;
import android.view.View;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InjectUtils {
public static void injectEvent(Activity activity) {
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(EventType.class)) {
EventType eventType = annotationType.getAnnotation(EventType.class);
// OnClickListener.class
Class listenerType = eventType.listenerType();
//setOnClickListener
String listenerSetter = eventType.listenerSetter();
try {
// 不需要关心到底是OnClick 还是 OnLongClick
Method valueMethod = annotationType.getDeclaredMethod("value");
int[] viewIds = (int[]) valueMethod.invoke(annotation);
method.setAccessible(true);
ListenerInvocationHandler<Activity> handler = new ListenerInvocationHandler(activity, method);
Object listenerProxy = Proxy.newProxyInstance(listenerType.getClassLoader(),
new Class[]{listenerType}, handler);
// 遍历注解的值
for (int viewId : viewIds) {
// 获得当前activity的view(赋值)
View view = activity.findViewById(viewId);
// 获取指定的方法(不需要判断是Click还是LongClick)
// 如获得:setOnClickLisnter方法,参数为OnClickListener
// 获得 setOnLongClickLisnter,则参数为OnLongClickLisnter
Method setter = view.getClass().getMethod(listenerSetter, listenerType);
// 执行方法
setter.invoke(view, listenerProxy); //执行setOnclickListener里面的回调 onclick方法
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 还可能在自定义view注入,所以是泛型: T = Activity/View
*
* @param <T>
*/
static class ListenerInvocationHandler<T> implements InvocationHandler {
private Method method;
private T target;
public ListenerInvocationHandler(T target, Method method) {
this.target = target;
this.method = method;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return this.method.invoke(target, args);
}
}
}
5、使用
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtils.injectEvent(this);
}
@OnClick({R.id.btn1, R.id.btn2})
public void click(View view) {
switch (view.getId()) {
case R.id.btn1:
Log.i(TAG, "click: 按钮1");
break;
case R.id.btn2:
Log.i(TAG, "click: 按钮2");
break;
}
}
@OnLongClick({R.id.btn1, R.id.btn2})
public boolean longClick(View view) {
switch (view.getId()) {
case R.id.btn1:
Log.i(TAG, "longClick: 按钮1");
break;
case R.id.btn2:
Log.i(TAG, "longClick: 按钮2");
break;
}
return false;
}
}