Android注解学习之事件注解

本文介绍了一种使用注解的方式实现Android中视图的点击事件。通过自定义注解和反射机制,可以简化传统点击事件设置的过程。文章详细解释了自定义注解的创建过程及其如何与视图绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
}
  1. 通过注解反射的方式,实现事件的注入
  /**
     * 事件的注入
     */
    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值