注解是一种元数据,可以添加到java代码中,类、方法、变量、参数、包都可以被注解,注解对注解的代码没有直接的影响。
注解是在解析的过程中做出了相应的处理,注解仅仅是一个标记。
定义一个注解的关键字是@interface
元注解
元注解共有四种 @Retention, @Target, @Inherited, @Documented
- @Retention 保留的范围,默认值为class,可选值有三种
SOURCE:只在源码中可用
CLASS:在源码和字节码中可用
RUNTIME:在源码、字节码、运行时均可用
@Target: 表示可以用来修饰哪些元素,如TYPE/METHOD/CONSTRUCTOR/FIELD/PARAMETER等,未标识及代表可以修饰所有
@Inherited:是否可以被继承,默认为false
@Documented: 是否会被保存到javadoc文档中
自定义注解–实现findViewById()
第一步定义注解:
1 2 3 4 5 6 7 8 9
| @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ViewInject {
int value();
/* parent view id */ int parentId() default 0; }
|
第二步处理注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class ViewUtils {
private ViewUtils() { }
public static void inject(Activity activity) { injectObject(activity, new ViewFinder(activity)); }
@SuppressWarnings("ConstantConditions") private static void injectObject(Object handler, ViewFinder finder) {
Class<?> handlerType = handler.getClass();
// inject view Field[] fields = handlerType.getDeclaredFields(); if (fields != null && fields.length > 0) { for (Field field : fields) { ViewInject viewInject = field.getAnnotation(ViewInject.class); if (viewInject != null) { try { View view = finder.findViewById(viewInject.value(), viewInject.parentId()); if (view != null) { field.setAccessible(true); field.set(handler, view); } } catch (Throwable e) { e.printStackTrace(); } } } }
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class ViewFinder {
private Activity activity;
public ViewFinder(Activity activity) { this.activity = activity; }
public View findViewById(int id) { return activity.findViewById(id); }
public View findViewById(int id, int pid) { View pView = null; if (pid > 0) { pView = this.findViewById(pid); }
View view = null; if (pView != null) { view = pView.findViewById(id); } else { view = this.findViewById(id); } return view; }
}
|
第三步 activity调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class DIYAnnotationActivity extends AppCompatActivity {
@ViewInject(R.id.textView) private TextView textView;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_annotation);
ViewUtils.inject(this);
textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { textView.setText("成功了!"); } });
}
}
|
基本上是通过获取activity实例,然后通过反射遍历field找到用到这个注解的地方,然后进行findviewbyid的进行,之后返回view的实例