//copy了一个类似的,给大家个参考
*/
--------------------- 作者:c_煜杰 来源:CSDN 原文:https://blog.csdn.net/c_cayujie/article/details/68953665 版权声明:本文为博主原创文章,转载请附上博文链接! */
/** * @Target描述注解的使用范围 * 1.CONSTRUCTOR:用于描述构造器 2.FIELD:用于描述域 3.LOCAL_VARIABLE:用于描述局部变量 4.METHOD:用于描述方法 5.PACKAGE:用于描述包 6.PARAMETER:用于描述参数 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明 */ /** * @Retention 该Annotation被保留的时间长短 * 1.SOURCE:在源文件中有效(即源文件保留) 2.CLASS:在class文件中有效(即class保留) 3.RUNTIME:在运行时有效(即运行时保留) *///实现setContentView功能
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS) public @interface SetContent { int value() default -1; }
//实现findViewById功能
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
int value();
}
/**
* Created by admin on 2017/4/2.
* 注入解析器
* 单例
*/
public class MyAnnotationInject {
private static MyAnnotationInject INSTANCE;
private List<Object> mInjectObjs = new ArrayList<Object>();
public static MyAnnotationInject init() {
if (INSTANCE == null) {
INSTANCE = new MyAnnotationInject();
}
return INSTANCE;
}
/**
* 注册需要注入的类对象
* @param injectObj
*/
public void regist(@NonNull Object injectObj) {
if(mInjectObjs.contains(injectObj)){
return;
}
if (injectObj instanceof Activity) {
Activity activity = (Activity) injectObj;
//拿到注入的class对象
Class<Activity> clz = (Class<Activity>) activity.getClass();
try {
injectContentView(activity, clz);
injectView(activity, clz);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
mInjectObjs.add(injectObj);
}
/**
* 注入view
*/
private void injectView(Activity activity, Class<Activity> clz) throws IllegalAccessException {
//获得所有的属性,包括public、protected、private
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
//遍历所有属性,找到标有Bindview注解的属性
if (field.isAnnotationPresent(BindView.class)) {
//拿到BindView注解的值
BindView annotation = field.getAnnotation(BindView.class);
int viewId = annotation.value();
//如果是私有属性,修改属性赋值之前必须加可修改权限
field.setAccessible(true);
//给属性重新赋值,参数1:要修改的属性的对象 , 参数2 : 新值
field.set(activity, activity.findViewById(viewId));
}
}
}
/**
* 注入activity布局
*/
private void injectContentView(Activity activity, Class<Activity> clz) {
if (clz.isAnnotationPresent(SetContent.class)) {
//拿到SetContent注解的值
SetContent annotation = clz.getAnnotation(SetContent.class);
int resId = annotation.value();
if (resId != -1) {
activity.setContentView(resId);
}
}
}
//定义完上边的注解,就可以使用了
@SetContent(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv_text)
private TextView textView;
}
/**
* 注销需要注入的类对象
* @param injectObj
*/
public void unRegist(Object injectObj) {
if (mInjectObjs.contains(injectObj)){
mInjectObjs.remove(injectObj);
}
}