//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); } }