框架剖析:
理解:什么是注解?严谨的来说,注解提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
Java 注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。注解包含在 java.lang.annotation 包中。
首先呢ButterKnife 就是使用注解模式来辅助我们,自动帮我们findViewById()来帮助我们给控件赋值,或是辅助方法的执行。
1.就是属性的绑定
2.就是方法的绑定
一、首先我们写两个Annotation(1.字段 2.方法)
//字段
@Retention(RetentionPolicy.RUNTIME)//运行时加载 节省资源
@Target(ElementType.FIELD)//变量
public @interface InjectView {
int ID();
}
//方法
@Retention(RetentionPolicy.RUNTIME) // 运行时加载 节省资源
@Target(ElementType.METHOD)//方法
public @interface OnClick {
int value();//传递要点击的布局id
}
二、我们写一个使用的工具类
public class ViewUtils {
public static void bind(Activity activity){
bindFeild(activity);//查找ID
bindOnClick(activity);//点击事件
}
private static void bindOnClick(final Activity activity) {
Class<? extends Activity> aClass = activity.getClass();
Method[] declaredMethods = aClass.getDeclaredMethods();//获取所有方法
for (final Method methodL:declaredMethods){//遍历
OnClick annotation = methodL.getAnnotation(OnClick.class);//获取方法
if(annotation!= null){//判断不为空
int value = annotation.value();
View viewById = activity.findViewById(value);
methodL.setAccessible(true);//暴力访问,获取私有字段
viewById.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
methodL.invoke(activity);//使用反射来调用方法
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
}
}
}
private static void bindFeild(Activity activity) {//查找ID
Class<? extends Activity> clazz = activity.getClass();//获取布局
Field[] declaredFields = clazz.getDeclaredFields();//获取所有属性
for (Field field:declaredFields){
InjectView annotation = field.getAnnotation(InjectView.class);
if(annotation!= null){
int id = annotation.ID();
View viewById = activity.findViewById(id);
field.setAccessible(true);
try {
field.set(activity,viewById);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
三、最后我们使用的时候就可以调用
public class MainActivity extends AppCompatActivity {
@InjectView(ID = R.id.btn)//使用我们的注解模式
private Button but;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.bind(this);
}
@OnClick(value = R.id.btn)
private void OnClick(){
Toast.makeText(MainActivity.this,"我被点击了",Toast.LENGTH_SHORT).show();
}
}