@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface OnClick { int value(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface OnLongClick { int value(); }
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface BindString { int value(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface BindView { int value(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface OnTouch { int value(); }
package com.example.administrator.mvplibao.utils.my_butter_knife; import android.app.Activity; import android.app.Fragment; import android.content.Context; import android.view.MotionEvent; import android.view.View; import com.example.administrator.mvplibao.utils.my_butter_knife.annotation.BindString; import com.example.administrator.mvplibao.utils.my_butter_knife.annotation.BindView; import com.example.administrator.mvplibao.utils.my_butter_knife.annotation.OnClick; import com.example.administrator.mvplibao.utils.my_butter_knife.annotation.OnLongClick; import com.example.administrator.mvplibao.utils.my_butter_knife.annotation.OnTouch; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Created by Administrator on 2016/9/26. */ public class MyButterKnife { public static void bind(Activity activity) { initFiled(activity, activity.getWindow().getDecorView()); initMethod(activity, activity.getWindow().getDecorView()); } /** * 绑定Fragment和其他对象 * * @param object fragment对象 * @param view 要查找的控件树对象 */ public static void bind(Object object, View view) { initFiled(object, view); initMethod(object, view); } private static void initMethod(final Object object, View view) { Class<?> aClass = object.getClass();//获取要反射的对象上的字节码对象 Method[] declaredMethods = aClass.getDeclaredMethods(); for (final Method method : declaredMethods) {//获取所有方法对象 method.setAccessible(true); OnClick annotation = method.getAnnotation(OnClick.class);//获取方法对象上的注解 if (annotation != null) { int id = annotation.value(); View temp = view.findViewById(id);//获取View并设置点击事件 temp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { method.invoke(object);//反射调用对象上的方法 } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }); continue; } OnLongClick annotationL = method.getAnnotation(OnLongClick.class); if (annotationL != null) { int id = annotationL.value(); View temp = view.findViewById(id); temp.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { try { method.invoke(object); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return true; } }); continue; } OnTouch annotationT = method.getAnnotation(OnTouch.class); if (annotationT != null) { int id = annotationT.value(); View temp = view.findViewById(id); temp.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { try { method.invoke(object); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return true; } }); continue; } } } private static void initFiled(Object object, View view) { Class<?> aClass = object.getClass(); Field[] declaredFields = aClass.getDeclaredFields(); for (Field field : declaredFields) { field.setAccessible(true); //反射加载View BindView annotation = field.getAnnotation(BindView.class); if (annotation != null) { int id = annotation.value(); View temp = view.findViewById(id); try { field.set(object, temp); } catch (IllegalAccessException e) { e.printStackTrace(); } continue; } //反射加载String资源 BindString annotations = field.getAnnotation(BindString.class); if (annotations != null) { int id = annotations.value(); Context context = null; if (object instanceof Context) context = (Context) object; else if (object instanceof Fragment) context = ((android.support.v4.app.Fragment) object).getContext(); if (context == null) continue; String str = context.getResources().getString(id); try { field.set(object, str); } catch (IllegalAccessException e) { e.printStackTrace(); } continue; } } } }