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

}

使用方法:略。

相关推荐
Gary Studio13 小时前
安卓HAL编写
android
_李小白16 小时前
【android opencv学习笔记】Day 2: Mat类(图片数据结构体)
android·opencv·学习
jinanwuhuaguo17 小时前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw
小怪吴吴19 小时前
idea 开发Android
android·java·intellij-idea
xiaoyan201520 小时前
2026爆肝!Flutter3.41纯手撸微信聊天APP原生应用
android·flutter·dart
jinanwuhuaguo21 小时前
OpenClaw协议霸权——从 MCP 标准到意图封建化的政治经济学(第十八篇)
android·人工智能·kotlin·拓扑学·openclaw
撩得Android一次心动21 小时前
Android Room 数据库详解【源码篇】
android·数据库·android jetpack·room
TO_ZRG1 天前
Android WorkManager 完全入门指南
android
a8a3021 天前
Laravel 6.x新特性全解析
android
用户游民1 天前
Android 腾讯X5WebView如何禁止系统自带剪切板和自定义剪切板视图
android·java