您的位置:首页 > 移动开发 > Android开发

Android xUtils框架(二) ViewUtils

2015-09-08 08:10 267 查看
框架地址:https://github.com/wyouflf/xUtils
作用:完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。

UI绑定:

@ContentView(R.layout.view_acti)//setContentView 注解在activity的声明上方

@ViewInject(R.id.lv_test) //反射view 注解在一个view声明上

@ResInject(id=R.string.app_name, type=ResType.String) //资源反射 ResType中定义了res/values下的一些资源类型

@PreferenceInject("key") //注解在一个Preference组件上 value为它的key值

ViewUtils.inject(activity);//通过反射,查找相应view的,并初始化

事件绑定

@OnClick(R.id.btn_test) //将一个自定义的方法绑定到一个view的事件上

package com.lidroid.xutils.view.annotation 包下,定义了一些常见的事件,它们有个特点,即都只有一个内部实现方法

事件绑定并执行的流程分析
@ViewInject(R.id.btn_test)
private Button mButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ViewUtils.inject(this);

mButton.setText(label);

Method testButtonClickMethod;
try {
testButtonClickMethod = this.getClass().getMethod("testButtonClick", View.class);
MyOnClick onClick = testButtonClickMethod.getAnnotation(MyOnClick.class);
MyEventBase eventBase = onClick.annotationType().getAnnotation(MyEventBase.class);
Class<?> listenerType = eventBase.mlistenerType();//View.OnClickListener.class
String listenerSetter = eventBase.mlistenerSetter();//setOnClickListener
String methodName = eventBase.mmethodName();//onClick

MyDynamicHandler dynamicHandler = new MyDynamicHandler(ViewActivity.this);
dynamicHandler.addMethod(methodName, testButtonClickMethod);//将实质要调用的method加入到handler内部的map集中
Object listener = Proxy.newProxyInstance(//动态代理
listenerType.getClassLoader(),
new Class<?>[]{listenerType},
dynamicHandler);
Method setEventListenerMethod = mButton.getClass().getMethod(listenerSetter, listenerType);//setOnClickListener-method
/*
* onCreate()直接执行的:
* 		首先这里调用的是:mButton.setOnClickListener(listener);
* 		listener传进代理对象
* 	  		 注意:dynamicHandler的invoke
*
* touch过后:
* 		dispatchTouchEvent的一次action-down和action-up之后,触发view的onClick-event
*		OnClickListener已经设置为代理对象listener了
*		就会调用listener对应的处理器dynamicHandler.invoke()
*		invoke中:最终执行testButtonClick方法
*
*/
setEventListenerMethod.invoke(mButton, listener);

} catch (Exception e) {
e.printStackTrace();
}

}
@MyOnClick(R.id.btn_test)
public void testButtonClick(View v) {
LogUtil.print("点击了button");
}

@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyEventBase {
Class<?> mlistenerType();

String mlistenerSetter();

String mmethodName();
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MyEventBase(
mlistenerType = View.OnClickListener.class,
mlistenerSetter = "setOnClickListener",
mmethodName = "onClick")
private static @interface MyOnClick {
int[] value();
int[] parentId() default 0;
}

public class MyDynamicHandler implements InvocationHandler {
private WeakReference<Object> handlerRef;
private final HashMap<String, Method> methodMap = new HashMap<String, Method>(1);

public MyDynamicHandler(Object handler) {
this.handlerRef = new WeakReference<Object>(handler);
}

public void addMethod(String name, Method method) {
methodMap.put(name, method);
}

public Object getHandler() {
return handlerRef.get();
}

public void setHandler(Object handler) {
this.handlerRef = new WeakReference<Object>(handler);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object handler = handlerRef.get();//viewActivity
if (handler != null) {
String methodName = method.getName();
System.out.println("InvocationHandler.invoke--methodName:" + methodName);
method = methodMap.get(methodName);
if (method != null) {
return method.invoke(handler, args);
}
}
return null;
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
System.out.println("dispatch");
return super.dispatchTouchEvent(ev);
}


类似的,其他一些事件都会像上面这样用动态代理的形式,来绑定你使用事件注解的方法和对应事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android