前言
最近看到注解一块,看到ButterKnife的源码解析,于是就想仿ButterKnife的BindView,弄一个自定义的注解,来对Activity中的控件进行注解,避免通过书写findViewById获取对象(注意:其实BindView的底层还是通过findViewById获取的控件对象)。
自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface BindView {
@IdRes int id() default -1;
}
自定义注解工具
public class InjectUtils {
/**
* 解析注解,通过注解获取注解的Field成员变量
* @param activity
*/
public static void inject(Activity activity){
Field[] fields=activity.getClass().getDeclaredFields();
AccessibleObject.setAccessible(fields,true);
//遍历获取到的每一个成员变量
for (Field field: fields) {
boolean isAnnotation=field.isAnnotationPresent(BindView.class);
if (isAnnotation){//从Activity中找出当前添加了BindView注解的成员变量
BindView bindView=field.getAnnotation(BindView.class);
//通过bindView获取得到当前控件的viewId
int viewId=bindView.id();
//还是使用findViewById通过viewId获取得到view对象
View view=activity.findViewById(viewId);
try {
//获取到当前成员变量的类型
Class filedType=field.getType();
//把得到的View对象强制转换为filedType类型
field.set(activity,filedType.cast(view));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
自定义注解的使用
public class MainActivity extends AppCompatActivity {
@BindView(id = R.id.tv_text)
TextView tv_text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtils.inject(this);
tv_text.setText("我是Text,成功的通过自定义注解获取到了我,并修改了我显示的内容");
}
}
展示效果: