简单实现id注解(1)

1.全部代码

1.
2.
3.
4.

2.步骤

1.参数注解的实现:
1.参照框架模仿写注解
private static final String TAG = "MainActivity";//干扰
    @ViewInject(R.id.tv1)
    private TextView tv1;
    @ViewInject(R.id.tv2)
    private TextView tv2;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewUtils.inject(this);//绑定注解
        Log.d("TAG", "onCreate: "+tv1.getText()+"\n"+tv2.getText());//监测是否找id成功
    }
2.编写注解类@ViewInject,它有一个int类型的参数
@Retention(RetentionPolicy.RUNTIME)//一直作用(编码---》虚拟机)
@Target(ElementType.FIELD)//参数
public @interface ViewInject {
    int value();//value是注解提供的方法,类似万能标记,可以用于通过标记,拿到它
}
3.ViewUtils.inject的实现,绑定id
public static void inject(Activity activity){
        bindView(activity);
        //bindOnClick(activity);
    }
4.bindView()方法的实现
  1. 获取activity的字节码,再获取字节码上的成员变量组
/**
         * 获取activity的字节码
         */
        Class<? extends Activity> aClass = activity.getClass();
        /**
         * 获取到字节码对应的Filed
         */
        Field[] declaredFields = aClass.getDeclaredFields();

在这里插入图片描述

  1. 获取带有注解的成员变量
/**
         * 遍历字段,得到我们想要的字段(有@ViewInject)
         */
        for (Field declaredField : declaredFields) {//这里会全部遍历,遍历三次
            //获取字段上面有注解
            ViewInject viewInject = declaredField.getAnnotation(ViewInject.class);//有的返回有值,没有的返回null
            if (viewInject!=null){
                //获取当前注解的值id
                int resId = viewInject.value();
                //通过调用activity的findViewById方法,获取当前控件id
                View viewById = activity.findViewById(resId);
                //将当前的view设置给当前的Filed
                declaredField.setAccessible(true);//暴力反射
                //给activity对象的filed字段设置值为view的对象
                try {
                    declaredField.set(activity,viewById);//类,成员变量
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }else {
                //TODO:不做什么
            }

        }

在这里插入图片描述

2.方法注解的实现:
1.

为方法注解

@OnClick(R.id.bt_press)
    private void clickMe(View view){
        Toast.makeText(this, "我被点击了", Toast.LENGTH_SHORT).show();
    }
2.OnClick注解类
@Retention(RetentionPolicy.RUNTIME)//一直保留到虚拟机中
@Target(ElementType.METHOD) //方法
public @interface OnClick {
    int value();//R.id.xx是int类型
}
3.bindOnClick
private static void bindOnClick(final Activity activity) {
        //获取字节码
        Class<? extends Activity> aClass = activity.getClass();
        //获取所有方法
        Method[] declaredMethods = aClass.getDeclaredMethods();
        /**
         * 遍历所有方法
         */
        for (final Method declaredMethod : declaredMethods) {
            //获取当前方法上有注解类
            OnClick onClick = declaredMethod.getAnnotation(OnClick.class);
            //判断是否为空
            if (onClick!=null) {
                //获取注解的值
                int resId = onClick.value();
                //获取id对应的view
                final View view = activity.findViewById(resId);
                //给当前的View绑定点击监听事件
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //通过反射调用当前的用户方法,匿名内部内里面访问这个方法的局部变量,这个变量要final
                        declaredMethod.setAccessible(true);//暴力反射

                        try {
                            declaredMethod.invoke(activity,view);//反射回方法
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }

3.反思总结

1.参数注解的实现
2.
3.
4.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值