注:本篇博客的代码效果基于运行时注解
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;
}
}
本文详细介绍如何使用Java运行时注解实现自定义的BindView和OnClick功能,通过反射机制解析注解并绑定视图和点击事件。
1705

被折叠的 条评论
为什么被折叠?



