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

}

使用方法:略。

相关推荐
darling33121 小时前
mysql 自动备份以及远程传输脚本,异地备份
android·数据库·mysql·adb
你刷碗21 小时前
基于S32K144 CESc生成随机数
android·java·数据库
TheNextByte11 天前
Android上的蓝牙文件传输:跨设备无缝共享
android
言之。1 天前
Kotlin快速入门
android·开发语言·kotlin
符哥20081 天前
Android 权限分类说明
android
大模型玩家七七1 天前
安全对齐不是消灭风险,而是重新分配风险
android·java·数据库·人工智能·深度学习·安全
李少兄1 天前
MySQL 中为时间字段设置默认当前时间
android·数据库·mysql
俩个逗号。。1 天前
修改Android resource dimens大小之后不生效
android
2501_915918411 天前
在 iOS 环境下查看 App 详细信息与文件目录
android·ios·小程序·https·uni-app·iphone·webview
落羽的落羽1 天前
【Linux系统】从零实现一个简易的shell!
android·java·linux·服务器·c++·人工智能·机器学习