要使用注解,那么必须会自定义注解,在学自定义注解之前, 需要知道元注解 meta-annotation(四个),他们被用来对其他注解提供说明; 注意自定义注解时需要用到反射相关内容
元注解:
元注解就是负责注解其他注解
1、@Target
2、@Retention
3、@Documented
4、@Inherited
目前主要使用的是前两个
@Target 说明了Annotation所修饰的对象范围
取值(ElementType)的取值范围有:
public enum ElementType {
/**
* Class, interface or enum declaration.
*/
TYPE,
/**
* Field declaration.
*/
FIELD,
/**
* Method declaration.
*/
METHOD,
/**
* Parameter declaration.
*/
PARAMETER,
/**
* Constructor declaration.
*/
CONSTRUCTOR,
/**
* Local variable declaration.
*/
LOCAL_VARIABLE,
/**
* Annotation type declaration.
*/
ANNOTATION_TYPE,
/**
* Package declaration.
*/
PACKAGE
}
取值(RetentionPolicy)的取值范围有
public enum RetentionPolicy {
/**
* Annotation is only available in the source code.
*/
SOURCE,
/**
* Annotation is available in the source code and in the class file, but not
* at runtime. This is the default policy.
*/
CLASS,
/**
* Annotation is available in the source code, the class file and is
* available at runtime.
*/
RUNTIME
}
@Documented 将注释包含在javadoc中
@Inhertied 允许子类继承父类的注释
自定义注解
定义注解格式:
public @interface 注解名{ 定义体 }
定义体内每个方法的名称就是参数的名称,返回值类型就是参数的类型
返回值类型只能是 基本数据类型、Enum、String、Class、Annotation以及这一些类型的数组
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
* @author peida
*
*/
public enum Color{ BULE,RED,GREEN};
/**
* 颜色属性
* @return
*/
Color fruitColor() default Color.GREEN;
}
一个自定义注解的案例
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
//用来注解布局文件
public @interface LayoutInject {
int value()default 0; //布局的id
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
int value()default 0; //控件的id
boolean isClick() default false; //控件上点击事件
}
public class AnnotationUtil {
//设置布局文件,通过在类上面设置注解
public static void setContentView(Activity activity){
if(activity.getClass().isAnnotationPresent(LayoutInject.class)){
LayoutInject inject = activity.getClass().getAnnotation(LayoutInject.class);
activity.setContentView(inject.value());
}
}
public static void findView(Activity activity){
Field[] fields = activity.getClass().getDeclaredFields();
if(fields.length==0 && fields==null){
return;
}
try {
for (Field field:fields){
if(field.isAnnotationPresent(ViewInject.class)){
ViewInject viewInject = field.getAnnotation(ViewInject.class);
int id = viewInject.value();
if(id>0){
View view = activity.findViewById(id);
//强制反射私有变量
field.setAccessible(true);
field.set(activity,view);
if(viewInject.isClick()){
view.setOnClickListener((View.OnClickListener) activity);
}
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public class BaseAcitvity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
AnnotationUtil.setContentView(this);
AnnotationUtil.findView(this);
}
}
@LayoutInject(value = R.layout.activity_main)
public class MainActivity extends BaseAcitvity implements View.OnClickListener {
@ViewInject(value = R.id.tv_onclick,isClick = true)
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("xiaoma","你好啊a");
}
@Override
public void onClick(View v) {
Log.e("xiaoma","点击");
switch (v.getId()){
case R.id.tv_onclick:
Toast.makeText(this,"点击事件",Toast.LENGTH_SHORT).show();
break;
}
}
}