注解介绍
Java中的注解非常的多,在Android中最主要的还是这2个注解,@Target和@Retention。
@Target
@Target是什么?
定义了在哪些地方可以使用注解,比如:类,属性,方法,参数,构造方法,局部变量,包声明等。
@Target注解有几种值?
1、TYPE:类、接口、枚举
2、FIELD:在属性上声明
3、METHOD:在方法上声明
4、PARAMETER:在参数上声明
5、CONSTRUCTOR:在构造上声明
6、ANNOTATION_TYPE:注解类型声明
7、LOCAL_VARIABLE:局部变量声明
8、PACKAGE:包声明
@Retention
@Retention是什么?
定义了注解在哪些阶段可以使用,源码阶段、class阶段、运行时阶段。
@Retention的值有哪些?
1、RetentionPolicy.SOURCE:注解只能存在于源码中。
2、RetentionPolicy.CLASS:注解一直存在于字节码阶段。
3、RetentionPolicy.RUNTIME:注解存在于运行时阶段。
利用注解实现ButterKnife效果
1、定义OnClick注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int value() default -1;
}
2、定义BindView注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
int value() default -1;
}
3、定义ButterKnife类
public class ButterKnife {
@RequiresApi(api = Build.VERSION_CODES.N)
public static void bind(final Activity activity) {
if (activity == null) {
return;
}
try {
// 获取字节码
Class clazz = activity.getClass();
// 遍历所有的方法,获取方法上是否有OnClick的注解,如果有注解,首先通过id找到对应的控件,
// 然后设置点击事件,然后再通过反射来执行方法。
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
final OnClick onClick = method.getDeclaredAnnotation(OnClick.class);
if (onClick != null) {
final View view = activity.findViewById(onClick.value());
// 设置可以访问
method.setAccessible(true);
// 设置点击事件,然后再通过反射调用方法。
view.setOnClickListener(v -> {
try {
method.invoke(activity, view);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
// 遍历所有的字段,然后检测是否有BindView注解,如果有注解,那么执行findViewById的操作。
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
BindView bindView = field.getDeclaredAnnotation(BindView.class);
if (bindView != null) {
View view = activity.findViewById(bindView.value());
//设置可以访问
field.setAccessible(true);
// 将控件设置给field对象,这句话很关键
field.set(activity, view);
}
}
} catch (Exception e) {
}
}
}
4、然后在页面中调用
public class TestActivity extends AppCompatActivity {
@BindView(R.id.tv)
TextView tv;
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test5);
ButterKnife.bind(this);
tv.setText("Success");
}
@OnClick(R.id.tv)
public void onClick(View view) {
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show();
}
}