標籤:android 架構 xutils
架構地址: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;@Overrideprotected 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);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object handler = handlerRef.get();//viewActivityif (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;}}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {System.out.println("dispatch");return super.dispatchTouchEvent(ev);}
類似的,其他一些事件都會像上面這樣用動態代理的形式,來綁定你使用事件註解的方法和對應事件。
Android xUtils架構(二) ViewUtils