前言
在开发过程中,我们肯定会用到各种三方框架。在安卓开发中,有很多我们国人编写的优秀框架,Afinal,Zfinnal,Xutils等。这些框架功能非常强大。这里我们来说一下主题,在这些框架中我们可以发现都有绑定控件id的功能。也就是通过注解省略FindViewById的过程。近两年也有专门做这一种事的框架,如ButterKnife、dagger2等。那么这个看似有点高科技的功能是怎么实现的呢?今天我就来带大家一步一步自己做一个FindViewById的注解。另外。本文的阅读群体是掌握安卓基本开发的入门级工程师。阅读本文之前需要了解的相关知识有Java反射基础知识与常用API、Java注解的相关知识。现在,我们开始写一个Demo!
1)我们先创建一个新的Android工程。过程我不在叙述。创建好安卓工程后。看一下目录结构。这里我建了一个tools包。来存放相关的类与注解。
2)既然用到注解,我们首先要创建个注解,下面贴上我的代码。
@Target(ElementType.FIELD) //注解目标为域
@Retention(RetentionPolicy.RUNTIME) //运行时注解
public @interface BindView {
int value() default 0;//当前注解只需要一个值,所以我们用value 默认值为0
}
这里我创建了一个名为BindView的注解,使用了默认的成员value并赋默认值为0,通过元注解限定了该注解的目标范围和作用时间
3)注解类创建好了之后。我们该去使用这个注解了。
在使用这个注解之前,我们先思考一个问题。属性注解在使用的时候是需要通过反射获取属性实例并赋值的,我们在给View赋值的时候每次都需要做反射等操作。那么我们每次使用的时候都需要把这些代码重新写一遍么?答案肯定是NO,所以在这里我们将这个过程抽取出来。这里,我创建了一个InitBindView的类。在这个类中写了一个使用反射为view赋值的方法。下面我贴上代码。
public class InitBindView {
public static void initBindView(Activity activity) {
try {
Class<Activity> clazz = (Class<Activity>) activity.getClass();//通过getClass拿到activity实例
Field[] fields = clazz.getDeclaredFields();//通过反射拿到类内属性
//循环取出属性
for (Field field : fields) {
if (field.isAnnotationPresent(BindView.class)) {//判断属性是否使用注解
BindView inject = field.getAnnotation(BindView.class);//如果使用就获得该类上注解
int id = inject.value();
if (0 != id) {
field.setAccessible(true);//提高反射速度
field.set(activity, activity.findViewById(id));//给被注解属性赋值
}
}
}
} catch (Exception e) {
//捕获异常后处理
}
}
}
通过注释我们可以了解到在这个方法中我们都做了哪些操作。简述一下就是通过反射拿到Activity中属性,判断是否使用了注解,如果使用,取出注解value并复制给view
4)准备工作已经做好我们来开始使用这个注释吧。直接看代码。
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv_annotation)
private TextView tvAnnotation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InitBindView.initBindView(this);
tvAnnotation.setText("Hello Annotation!!!");
}
}
在这个Activity的布局中,只有一个TextView,id为tv_annotation,我们通过InitBindView类中的静态方法先做反射的初始化操作,将Activity实例传入。然后通过BindView注解给View赋值,省去了FindViewById的过程。然后我们给这个TextView设置文本 Hello Annotation!!! 我这里截图一张来看下运行结果吧。
可以看到,我们已经成功使用BindView注解绑定了控件与id。
下面我附上项目地址。
https://github.com/JingbinChow/BindViewAnnotation