注解+反射+动态代理实现View点击事件的注入

首先添加点击事件注解

	//onClick注解
	@Target(ElementType.METHOD)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface OnClick {
	    int[] value();
	}
	
	//onLongClick
	@Target(ElementType.METHOD)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface OnLongClick {
	    int[] value();
	}

通过反射方式获取到带有此注解的Method

	//通过传入的activity获取对应的activiy类,用于获取其中添加了我们注解的方法
	Class<? extends Activity> activityClass = activity.getClass();
	            Method[] declaredMethods = activityClass.getDeclaredMethods();
	            //拿到对应实例的所有Method
	            for (Method method : declaredMethods) {
	                //获取方法的注解
	                Annotation[] annotations = method.getAnnotations();
	                for (Annotation annotation : annotations) {
	                    Class<? extends Annotation> annotationType = annotation.annotationType();
	                    //annotationType.isAnnotationPresent(OnClick.class)
						//TODO 通过判断annotationType.isAnnotationPresent 是否为对应的点击事件
						//然后findViewById查找对应的view来设置对应的点击事件
						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();
	}


	//TODO 通过判断annotationType.isAnnotationPresent 是否为对应的点击事件
 	Class<? extends Annotation> annotationType = annotation.annotationType();
    //判断注解 是否被EventType注解
     if (annotationType.isAnnotationPresent(EventType.class)) {
         //拿到注解上的EventType
         EventType eventType = annotationType.getAnnotation(EventType.class);
         String listenerSetter = eventType.listenerSetter();
         Class listenerType = eventType.listenerType();

         //拿到click方法的value值
         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);
             //找到点击事件setOnclickListener(new OnClickListener(){})
             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;
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值