一、采用注解来注入Activity中的布局和控件:
a、了解注解-Annotation
i、注解是程序中的一种标记也叫做元数据,在程序中加上注解相当于为程序打上某种标记。
详细了解注解:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
b、目标:
每次创建Activity的时候总是在setContenteView()方法中填入一个布局文件
对于页面中使用的控件View总不管是用到多少个控件总是得不断的通过findViewById方法来得到相关控件
所以我们这次的目标就是打破这种固有的开发模式采用一种新的模式开发:通过注解来完成对于Activity中布局文件和控件的注入
c、开发思路:
i、整体思路:
ii、采用注解的参数来记录Activity布局文件和控件的id 。
ii、然后采用反射机制得到注解中的参数的值--id
ii、采用反射机制得到Activity的反射,从而将注解中记录的id值分别设置到setContentView和findViewById中
i、利用注解来记录Activity布局文件id R.layout.XXX 以及控件的id R.id.XXX 将这两种值分别记录到注解的参数中
i、Activity整体布局id属于类级别的内容 控件id属于成员变量级别的内容 所以我们必须得定义 两种类型的注解:TYPE 和 FIELD
分别作用于类 和 成员变量
i、我们知道得到注解的方式有一下几种:
ii、Class--反射
ii、Constructor--构造函数
ii、Field--成员变量
ii、Method--成员方法
ii、Package
而通过反射可以得到Constructor Field Method 所以这次我们主要采用反射来完成,通过反射得到TYPE类型的注解
通过反射得到Field 然后通过Field来得到成员变量的注解,最后采用反射得到Activity类中的方法setContentView和findViewById
的方法将注解参数中的值设置到这个方法,成功完成注入。
d、代码操作:
i、定义不同作用的两种注解一种用于TYPE 一种用于Field
i、写一个工具类将注解中的值分别注入到Activity的两个类方法中
二、实例代码:
a、定义注解:
@Target(ElementType.TYPE)//表示此注解用于 类
@Retention(RetentionPolicy.RUNTIME)//表示此注解存在于 运行时
public @interface ContentView {
int value() default -1;//表示此注解参数int类型value 默认-1
}
b、注解处理器:
/**
* 为setContetnView注入注解值
* **/
public static void injectSetContentView(Activity activity){
if(activity!=null){
Class<? extends Activity> clazz=activity.getClass();//得到activity的反射
ContentView contentAnnotation=clazz.getAnnotation(ContentView.class);//通过反射得到注解
if(contentAnnotation!=null && contentAnnotation.value()!=-1){
int contentViewLayoutid=contentAnnotation.value();
try{
Method contentMethod=clazz.getMethod(InjectKeys.ACTIVITY_SET_CONTENT_VIEW,int.class);//通过反射得到setContentView方法
contentMethod.setAccessible(true);
contentMethod.invoke(activity,contentViewLayoutid);//执行setContentView方法注入值
}catch (Exception e){
e.printStackTrace();
}
}
}
}
Activity中使用代码:
@ContentView(value = R.layout.purse_activity)//使用注解
public class PurseActivity extends StatisticsBaseActivity {
@ViewInject(R.id.account)
private TextView mAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
InjectUtils.injectSetContentView(this);//利用注解处理器处理将注解值植入到setContentView方法中
}