自定义注解实战,自己写一个FindViewById注解

前言

在开发过程中,我们肯定会用到各种三方框架。在安卓开发中,有很多我们国人编写的优秀框架,Afinal,Zfinnal,Xutils等。这些框架功能非常强大。这里我们来说一下主题,在这些框架中我们可以发现都有绑定控件id的功能。也就是通过注解省略FindViewById的过程。近两年也有专门做这一种事的框架,如ButterKnife、dagger2等。那么这个看似有点高科技的功能是怎么实现的呢?今天我就来带大家一步一步自己做一个FindViewById的注解。另外。本文的阅读群体是掌握安卓基本开发的入门级工程师。阅读本文之前需要了解的相关知识有Java反射基础知识与常用API、Java注解的相关知识。现在,我们开始写一个Demo!

1)我们先创建一个新的Android工程。过程我不在叙述。创建好安卓工程后。看一下目录结构。这里我建了一个tools包。来存放相关的类与注解。

自定义注解实战,自己写一个FindViewById注解_第1张图片









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 clazz = (Class) 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!!! 我这里截图一张来看下运行结果吧。

自定义注解实战,自己写一个FindViewById注解_第2张图片


可以看到,我们已经成功使用BindView注解绑定了控件与id。

下面我附上项目地址。

https://github.com/JingbinChow/BindViewAnnotation



你可能感兴趣的:(Android杂谈)