Android xUtils框架(二) ViewUtils
作用:
- 完全注解方式就可以进行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); }
类似的,其他一些事件都会像上面这样用动态代理的形式,来绑定你使用事件注解的方法和对应事件。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。