android 利用反射和注解绑定控件id和点击事件
以前写过一个工具类,利用java的反射和注解绑定安卓控件id和点击事件。 支持绑定activity、fragment、view的控件。记录下,后续抄着用。代码如下。
注解ViewId,用于绑定控件id:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewId {int id();
}
注解OnClick, 用于绑定控件点击事件:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 方法传一个view参数,或者不传参数* */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Onclick {int[] id();
}
工具类ViewUtil,绑定控件id、点击事件:
import java.lang.reflect.Field;
import java.lang.reflect.Method;import android.app.Activity;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.View;public class ViewUtil {Object widget;public void init(Activity activity) {widget = activity;init();}public void init(View view) {widget = view;init();}public void init(Fragment fragment) {widget = fragment;init();}private void init() {Field[] fields = widget.getClass().getDeclaredFields();if (fields != null && fields.length > 0) {for (Field field : fields) {ViewId viewId = field.getAnnotation(ViewId.class);if (viewId != null) {try {View view = findViewById(viewId.id());if (view != null) {field.setAccessible(true);field.set(widget, view);}} catch (Exception e) {Loger.e(e.getMessage());Loger.e("反射字段 "+field.getName()+" 获取异常");throw new RuntimeException(e);}}}}Method[] methods = widget.getClass().getDeclaredMethods();if (methods != null && methods.length > 0) {for (final Method method : methods) {Onclick onclick = method.getAnnotation(Onclick.class);if (onclick != null) {try {int[] ids = onclick.id();if (ids != null && ids.length > 0) {for (int i = 0; i < ids.length; i++) {final View view = findViewById(ids[i]);if (view != null) {method.setAccessible(true);view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {Class<?>[] parameterTypes = method.getParameterTypes();Log.e("zx","parameterTypes length"+ parameterTypes.length);if (parameterTypes == null|| parameterTypes.length == 0) {method.invoke(widget);} else if (parameterTypes != null&& parameterTypes.length == 1&& parameterTypes[0]==View.class) {method.invoke(widget, view);} else {throw new RuntimeException("传参异常");}} catch (Exception e) {Loger.e(e.getMessage());throw new RuntimeException(e);}}});}}}} catch (Exception e) {Loger.e(e.getMessage());throw new RuntimeException(e);}}}}}private View findViewById(int id) {if (widget != null && widget instanceof Activity) {return ((Activity) widget).findViewById(id);}if (widget != null && widget instanceof View) {return ((View) widget).findViewById(id);}if (widget != null && widget instanceof Fragment) {return ((Fragment) widget).getView().findViewById(id);}Loger.e("组件不支持");throw new RuntimeException("组件不支持");}}
使用方法:略。