Android ViewUtils注解框架自定义

时间:2021-11-11 15:57:45

ViewUtils模块:
android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定;
新的事件绑定方式,使用混淆工具混淆后仍可正常工作;
目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。
项目地址:https://github.com/wyouflf/xUtils

接下来将从UI和事件两个方面来自定义ViewUtils这样的一个框架:
首先创建一个注解类,MyInjectView.java代码如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface MyInjectView
{
int value();
}

说明:@Retention(RetentionPolicy.RUNTIME)指定了注解类的生命周期,包含了这个运行过程。@Target({ElementType.FIELD,ElementType.METHOD})指定了注解的类型,包含了UI注解以及方法注解。而int value();主要是获取注解资源的ID值。如果只需要注解UI控件,则只需修改为@Target(ElementType.FIELD)。

接下来写一个注解工具类,本质是采用了JAVA的反射机制,对注解了的UI对象还有方法对象进行遍历,动态进行绑定。下面先给出工具类代码MyViewUtils.java

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* Created by zhixiang on 2016/8/20.
*/

public class MyViewUtils
{

public static void inject(Activity activity)
{
bindView(activity);//绑定视图控件

bindMethod(activity);//绑定方法
}



private static void bindView(Activity activity)
{
Class<? extends Activity> aClass = activity.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field f: declaredFields)
{
MyInjectView annotation = f.getAnnotation(MyInjectView.class);
if (annotation!=null)//判断一下是否存在MyInjectView注解
{
int resID = annotation.value();
View view = activity.findViewById(resID);
f.setAccessible(true);
try {
f.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
private static void bindMethod(final Activity activity)
{
final Class<? extends Activity> aClass = activity.getClass();
Method[] declaredMethods = aClass.getDeclaredMethods();
for (final Method m:declaredMethods)
{
MyInjectView annotation = m.getAnnotation(MyInjectView.class);
if (annotation!=null)//判断一下是否存在MyInjectView注解
{
int resID = annotation.value();
final View view = activity.findViewById(resID);
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
m.setAccessible(true);
try {
m.invoke(activity,view);//当view点击时执行绑定的方法
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
}
}
}
}

使用时只需要像ViewUtils框架一样,在控件定义上进行注解,在方法前面注解,在onCreate中调用MyViewUtils.inject(this);即可。