android 利用反射和注解绑定控件id和点击事件

以前写过一个工具类,利用java的反射和注解绑定安卓控件id和点击事件。 支持绑定activity、fragment、view的控件。记录下,后续抄着用。代码如下。

注解ViewId,用于绑定控件id:

java 复制代码
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, 用于绑定控件点击事件:

java 复制代码
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、点击事件:

java 复制代码
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() {

										@Override
										public 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("组件不支持");
	}

}

使用方法:略。

相关推荐
Anhty8 小时前
2026九月最新变声器测评:iOS安卓双端适配,低延迟运行更稳定
android·人工智能·功能测试·ios·智能手机
渡我白衣9 小时前
并查集:基础认识与模拟实现
android·java·javascript·数据结构·c++·算法·并查集
Android-Flutter11 小时前
flutter GetX 详解
android·flutter
MyFreeIT12 小时前
Android Manual
android
hai_android13 小时前
AIDL 实现 IPC 进程间通信
android·android studio
AFinalStone15 小时前
Android 7系统无障碍服务(五)AccessibilityNodeInfo 的构建与查询
android·无障碍服务
今天要早睡_15 小时前
C++ 核心语法速过:命名空间、引用、函数重载与 nullptr 深度解析
android·java·c++
啦啦啦~~~22216 小时前
PC端+安卓端阅读器推荐!开源本地小说阅读器软件,
android·论文阅读·windows·开源软件·福昕阅读器
我命由我1234517 小时前
Android Jetpack Compose 开发问题:Unresolved reference ‘Icons‘.
android·java-ee·kotlin·android studio·android jetpack·android-studio·android runtime
爱笑鱼17 小时前
Android 系统启动机制(六):Zygote 创建 App 为什么走 Socket?哪些是源码事实,哪些是架构解释?
android·linux