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

}

使用方法:略。

相关推荐
方白羽5 小时前
Android APK安全防护
android·安全·apk
小黄人软件5 小时前
AndroidStudio老项目 macOS运行BlueTooth蓝牙串口助手(Android+Studio源码).rar
android·macos
00后程序员张5 小时前
苹果App Store上架指南:费用、原理与步骤详解
android·ios·小程序·https·uni-app·iphone·webview
天神哥哥啊5 小时前
cocos联调注意事项-安卓
android
TDengine (老段)5 小时前
TDengine TSDB 实战排障四(升级与兼容)
android·java·大数据·数据库·物联网·时序数据库·tdengine
蓝速科技6 小时前
政务自助终端信创选型与无人值守落地方案
android·大数据·数据库·人工智能·科技·技术分享·政务
硫酸锌017 小时前
在手机上运行Python增量备份手机数据到PC电脑
android·windows·python
hai_android8 小时前
子 View 被压小时,如何向父容器"告状"?——MEASURED_STATE_TOO_SMALL 向上传递机制
android·kotlin·android jetpack
AFinalStone8 小时前
Android 7 多用户源码解析(七)系统服务的多用户感知处理
android·系统架构·多用户
怪奇云呼军8 小时前
从 ElevenLabs 看工具调用:闪电智能 Voice Agent 的企业集成验收设计
android·大数据·运维·服务器·网络·人工智能·kotlin