1.全部代码
1.
2.
3.
4.
2.步骤
1.参数注解的实现:
1.参照框架模仿写注解
private static final String TAG = "MainActivity";//干扰
@ViewInject(R.id.tv1)
private TextView tv1;
@ViewInject(R.id.tv2)
private TextView tv2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.inject(this);//绑定注解
Log.d("TAG", "onCreate: "+tv1.getText()+"\n"+tv2.getText());//监测是否找id成功
}
2.编写注解类@ViewInject,它有一个int类型的参数
@Retention(RetentionPolicy.RUNTIME)//一直作用(编码---》虚拟机)
@Target(ElementType.FIELD)//参数
public @interface ViewInject {
int value();//value是注解提供的方法,类似万能标记,可以用于通过标记,拿到它
}
3.ViewUtils.inject的实现,绑定id
public static void inject(Activity activity){
bindView(activity);
//bindOnClick(activity);
}
4.bindView()方法的实现
- 获取activity的字节码,再获取字节码上的成员变量组
/**
* 获取activity的字节码
*/
Class<? extends Activity> aClass = activity.getClass();
/**
* 获取到字节码对应的Filed
*/
Field[] declaredFields = aClass.getDeclaredFields();
- 获取带有注解的成员变量
/**
* 遍历字段,得到我们想要的字段(有@ViewInject)
*/
for (Field declaredField : declaredFields) {//这里会全部遍历,遍历三次
//获取字段上面有注解
ViewInject viewInject = declaredField.getAnnotation(ViewInject.class);//有的返回有值,没有的返回null
if (viewInject!=null){
//获取当前注解的值id
int resId = viewInject.value();
//通过调用activity的findViewById方法,获取当前控件id
View viewById = activity.findViewById(resId);
//将当前的view设置给当前的Filed
declaredField.setAccessible(true);//暴力反射
//给activity对象的filed字段设置值为view的对象
try {
declaredField.set(activity,viewById);//类,成员变量
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}else {
//TODO:不做什么
}
}
2.方法注解的实现:
1.
为方法注解
@OnClick(R.id.bt_press)
private void clickMe(View view){
Toast.makeText(this, "我被点击了", Toast.LENGTH_SHORT).show();
}
2.OnClick注解类
@Retention(RetentionPolicy.RUNTIME)//一直保留到虚拟机中
@Target(ElementType.METHOD) //方法
public @interface OnClick {
int value();//R.id.xx是int类型
}
3.bindOnClick
private static void bindOnClick(final Activity activity) {
//获取字节码
Class<? extends Activity> aClass = activity.getClass();
//获取所有方法
Method[] declaredMethods = aClass.getDeclaredMethods();
/**
* 遍历所有方法
*/
for (final Method declaredMethod : declaredMethods) {
//获取当前方法上有注解类
OnClick onClick = declaredMethod.getAnnotation(OnClick.class);
//判断是否为空
if (onClick!=null) {
//获取注解的值
int resId = onClick.value();
//获取id对应的view
final View view = activity.findViewById(resId);
//给当前的View绑定点击监听事件
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通过反射调用当前的用户方法,匿名内部内里面访问这个方法的局部变量,这个变量要final
declaredMethod.setAccessible(true);//暴力反射
try {
declaredMethod.invoke(activity,view);//反射回方法
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}