View注入

来源:互联网 发布:python 打包 发布网站 编辑:程序博客网 时间:2024/06/06 14:29

使用Butterknife等视图注入工具可以减少findViewById这样没有营养的代码,那么这类工具的原理是什么呢?反射。通过反射,我们可以获取一个类的成员变量、方法,并进行修改和利用。那么我们就动手来写一个InjetView工具吧。
首先,创建一个注解类,用来标识要注解的变量。

@Target(ElementType.FIELD)//表示该注解作用于成员变量等@Retention(RetentionPolicy.RUNTIME)//表示该注解在运行时保留。public @interface InjetView {   int value();}

@Target、@Retention是元注解,就是不能在分割解释的注解(有点类似单位“个”,比如我们描述苹果可以说一个苹果,两个苹果,但是怎么来描述个呢?个是单位,O(∩_∩)O哈哈~),前者标识作用对象,后者标识作用生命期。
接下来我们创建该注解的处理器,总的思想就是根据传入Context的字节码,获取该字节码中含有InjetView注解的成员变量,通过反射调用findViewById()方法,获取到View,并赋予该字段。

public class InjetViewUtil {    public static void injet(Context context) throws NoSuchMethodException {        Class<? extends Context> aClass = context.getClass();        Field[] declaredFields = aClass.getDeclaredFields();        if (declaredFields != null) {            Method findViewById = aClass.getDeclaredMethod("findViewById", Integer.TYPE);            Object view;            int id;            InjetView annotation;            for (int i = 0; i < declaredFields.length; i++) {                annotation = declaredFields[i].getAnnotation(InjetView.class);                if (annotation != null) {                    id = annotation.value();                    try {                        declaredFields[i].setAccessible(true);                        view = findViewById.invoke(context, id);                        declaredFields[i].set(context, view);                    } catch (IllegalAccessException e) {                        e.printStackTrace();                    } catch (InvocationTargetException e) {                        e.printStackTrace();                    }                }            }        }    }}

大致上就是这样来实现View注入、bind,Butterknife还有@OnClick注解实现点击事件的处理等,等闲下来详细的分析下。

原创粉丝点击