- 介绍
在Android项目中,初始化View是必不可少的一部分,
public final View findViewById (int id)或者Activity中的 public View findViewById (int id)需要我们手动的转换View类型,基于泛型对其简单封装
@SuppressWarnings("unchecked")
public static <T> T findViewById(Activity activity, int viewId) {
return (T) activity.findViewById(viewId);
}
@SuppressWarnings("unchecked")
public static <T> T findViewById(View viewParent, int viewId) {
return (T) viewParent.findViewById(viewId);
}
但是在对View做单击、双击事件时仍然比较繁琐,下面我们开始基于反射制作我们自己的Ioc框架,Xutils、Andbase等原理类似。依赖注入具体到可以有构造注入、set函数注入、注解标注等,比较常用的就是基于注解标注的方式,在几个比较著名的依赖注入库中个人比较喜欢android annotations的注解名称,这里只以@ViewById 和 @Click为例
2. 注解定义和使用实例
@Retention(RetentionPolicy.RUNTIME) 表示注解保留到运行期
@Target(value = ElementType.FIELD) 表示注解只能标注在属性上
public @interface ViewById {
int value() default 0;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface Click {
int value() default 0;
}
使用实例
@ViewById(R.id.tv)
TextView tv;
@Click(R.id.tv)
public void onTvClicked() {
toast("ioc onClick");
}
@Click(R.id.tv)
public void onTvClicked(TextView tv) {
tv.setText("ioc onClick");
}
3.核心方法的编写
@ViewById(R.id.tv)
TextView tv;
上面在使用中仅仅对tv属性标注了注解,我们还需要在Activity运行时动态注入。
获取该Activity所有的属性信息
Class<? extends ActivityBase> clazz = getClass();
Field[] declaredFields = clazz.getDeclaredFields();
遍历其属性列表,找出标注了我们预定义的ViewById注解
for (Field field : declaredFields) {
if (field.isAnnotationPresent(ViewById.class)) {
ViewById annotationViewById = field.getAnnotation(ViewById.class);
if (annotationViewById != null) {
..............
}
}
}
通过注解获得Id信息,并把获取的View赋值给该属性
for (Field field : declaredFields) {
if (field.isAnnotationPresent(ViewById.class)) {
ViewById annotationViewById = field.getAnnotation(ViewById.class);
if (annotationViewById != null) {
int viewId = annotationViewById.value();
field.setAccessible(true);
try {
field.set(this, findViewById(viewId));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
}