首页 > 试题广场 >

简单实现一套view的注入框架()

[问答题]
简单实现一套view的注入框架()
我再次声明:
我 是 安卓 开发的程序员,不是***web开发程序员,你招web就写web啊,干嘛写成安卓开发!
mdzz
发表于 2019-03-13 20:11:33 回复(4)

//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);
     }
 }
编辑于 2019-03-22 20:47:04 回复(0)
Web后端表示 这个我看不懂
发表于 2019-03-18 20:30:37 回复(0)