使用注解自动注入View

2016-02-19 / 2 阅读 / Android

使用Activity时经常需要使用大量的View,每次都使用findViewById(id)便是一个非常耗时耗力的工程,而且代码繁多不易维护。因此减少这些耦合是必须的。幸亏java给我们提供了注解这项机制,这里变可以利用注解来简化代码。
形如:

    @Bind(R.id.btn)
    private Button btn;

倘若对注解不是太了解,可去查些资料稍微了解下。
注解说穿的就是在代码打个标记,关键是在处理这些标记的代码里。
废话不多说。下面开始讲解如何去处理注解。
大家都知道java的反射机制,这正是通过反射来做到的。

1.下面定义一个注解类

很像接口的定义方法。但不要漏了@
@Target和@Retention是源注解

    @Target(ElementType.FIELD)//表示用成员变量上
    @Retention(RetentionPolicy.RUNTIME)//运行时保留注解
    protected @interface Bind{
        int value() default -1;
    }

2.定义处理注解代码

        //获取类对象
        Class Class = this.getClass();
        //根据类对象获取所有字段数组
        Field[] fields = Class.getDeclaredFields();
        //下面遍历字段
        for (Field f : fields) {
            //f.isAnnotationPresent(Bind.class)查看是否打上了Bind这个注解
            if (f.isAnnotationPresent(Bind.class)){
                Bind bind = f.getAnnotation(Bind.class);
                int id = bind.value();//获取注解所给的值、便是View的id了
                if (id > 0){
                    f.setAccessible(true);//只有设为true才可以设置private的变量
                    try {
                        f.set(this, this.findViewById(id));
                    } catch (IllegalAccessException e) {
                        Log.e("Bind",f.getName()+"注入失败!");
                        e.printStackTrace();
                    }finally {
                        f.setAccessible(false);
                    }
                }
            }
        }
下面是我自定义BaseActivity,包括完整代码,以后只需继承,便可使用注解了
public class BaseActivity extends Activity {

    @Override
    public void setContentView(View view) {
        super.setContentView(view);
        inject();
    }

    @Override
    public void setContentView(int layoutResID) {
        super.setContentView(layoutResID);
        inject();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * 注入绑定注解
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    protected @interface Bind{
        int value() default -1;
    }

    /**
     * 自动注入解析
     */
    private void inject(){
        Class Class = this.getClass();
        Field[] fields = Class.getDeclaredFields();
        for (Field f : fields) {
            if (f.isAnnotationPresent(Bind.class)){
                Bind bind = f.getAnnotation(Bind.class);
                int id = bind.value();
                if (id > 0){
                    f.setAccessible(true);
                    try {
                        f.set(this, this.findViewById(id));
                    } catch (IllegalAccessException e) {
                        Log.e("Bind",f.getName()+"注入失败!");
                        e.printStackTrace();
                    }finally {
                        f.setAccessible(false);
                    }
                }
            }
        }
    }
}
相关推荐