Android仿butterknife注解实现bindview和onCLick(基于运行时注解)

注:本篇博客的代码效果基于运行时注解

Java注解Annotaion分为运行时注解也编译期注解,运行时注解主要基于反射机制实现,编译期注解主要借助apt实现,二butterknife的注解也是基于编译期注解来实现的。

编译期注解理解和实现起来都比运行时注解难度要大一些,主要是因为对于apt的理解以及一些相对生僻的api。所以本文先用运行时注解实现一个自定义的bindview和onClick。

bindview实现步骤:

第一步 首先定义一个MBindView接口,interface前边需要添加@标识符。在接口的顶部使用元注解@Target和@Retention

来对这个注解类进行注解,代码如下:

@Target(ElementType.FIELD)//对字段注解
@Retention(RetentionPolicy.RUNTIME)//运行时注解
public @interface MBindView {
    int value();
}

第二步 定义一个MyAnnotaion对注解元素进行解析

public static void bind(final Activity target){
        Class targetClass = target.getClass();//通过反射获取到使用了注解的activity的类对象
        Field[] fields = targetClass.getDeclaredFields();//获取这个类中所有字段,包括私有字段
        for(Field field:fields){//遍历所有字段
            field.setAccessible(true);//突破字段修饰符的访问控制
            MBindView bindView = field.getAnnotation(MBindView.class);//获取字段上的MyBindView注解
            if(bindView!=null){
                try{
                    View view = target.findViewById(bindView.value());
                    field.set(target,view);//将属性值设置到使用了MyBindView注解的字段上
                } catch(IllegalAccessException ex){
                    ex.printStackTrace();
                }
            }
        }
}

onClick实现步骤:

第一步 同bindview实现过程,需要将字段注解改为方法注解

@Target(ElementType.METHOD)//对方法注解
@Retention(RetentionPolicy.RUNTIME)//运行时注解
public @interface Click {
    int value();
}

第二步 在bind方法中添加对方法注解的解析过程

Method[] methods = targetClass.getDeclaredMethods();//获取所有方法
        for(final Method method:methods){//遍历方法列表
            method.setAccessible(true);//突破方法修饰符的访问限制
            Click click = method.getAnnotation(Click.class);//获取方法上的Click注解
            if(click!=null){
                View view = target.findViewById(click.value());

                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        try {
                            method.invoke(v,target);//通过invoke方法将事件传递到使用了click注解的方法中,并且是注解中的view能够触发事件
                        }catch(IllegalAccessException ex){
                            ex.printStackTrace();
                        }catch(InvocationTargetException ex){
                            ex.printStackTrace();
                        }

                    }
                });
            }
        }

在activity中使用自定义注解

@MBindView(R.id.tv_save)
TextView tv_save;

@MBindView(R.id.tv_catagory)
TextView tv_catagory;
@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_income);
        ScreenUtil.transparentStatus(this);
        ActivityUtil.pushActivity(this);
        MyAnnotaion.bind(this);
        edt_beizhu.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);
        edt_beizhu.setSingleLine(false);
}

@Click(R.id.rl_category)
    public void click(View view){
        switch (view.getId()){
            case R.id.rl_category:
                ActivityUtil.start(this, CategoryActivity.class);
                overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
                break;
          
        }
    }

 

你可能感兴趣的:(Android)