編輯:關於Android編程
注解是一種很優雅的書寫方式,也是我們的代碼變的簡潔,更加快捷方便編寫代碼。下面以綁定onclick實踐為例闡述注解的原理。
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @BaseEvent(listenerSetter = "setOnclickListener", listenerType = View.OnClickListener.class, methodName = "onclick") public @interface OnClick { int[] values(); }
BaseEvent用來制定需要綁定的方法名,事件的Listener,和綁定執行的方法名,BaseEvent的代碼如下
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface BaseEvent { Class> listenerType(); String listenerSetter(); String methodName(); }
@OnClick(R.id.download_btn) public void testUpload(View view) {}
思路:可以通過我們的注解對象中取得添加onclick注解的方法(testUpload)反射方法對象,對這個對象進行事件的綁定。動態代理View事件中的OnclickLister,向代理對象中添加方法對象(testUpload)。方法的添加在EventListenerManager管理類中完成。
EventLisernerManager中定義動態代理類:
public static void addEventMethod(Method method, Annotation annotation, Object value, Object handler, ViewFinder finder){ try{ View view = finder.findViewByInfo(value); if(view!=null){ BaseEvent baseEvent = annotation.annotationType().getAnnotation(BaseEvent.class); Class> listenerType = baseEvent.listenerType(); String listenerSetter = baseEvent.listenerSetter(); String methodName = baseEvent.methodName(); Object listener = listenerCache.get(value, listenerType); boolean addMethod = false; DynamicHandler dymicHandler = null; if(listener!=null){ dymicHandler = (DynamicHandler) Proxy.getInvocationHandler(listener); addMethod = (handler.equals(dymicHandler.getHandler())); if(addMethod){ dymicHandler.addMethod(methodName, method); } } if(!addMethod){ dymicHandler = new DynamicHandler(handler); dymicHandler.addMethod(methodName, method); listener = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class>[]{listenerType},dymicHandler); listenerCache.put(value, listenerType, listener); } //setListener Method setterMethod = view.getClass().getMethod(listenerSetter, listenerType); setterMethod.invoke(view, listener); } }catch(Exception e){ LogUtils.e(e.getMessage(),e); } }listener = Proxy.newProxyInstance(listenerType.getClassLoader(),new Class>[]{listenerType},dymicHandler);動態的代理了onClickListener。類中對代理對象進行的緩存:
//緩存代理對象 public final static DoubleKeyValueMap
解析注解添加方法:
Method[] methods = handlerType.getDeclaredMethods(); if(methods.length>0){ for(Method method:methods){ Annotation[] annotations = method.getDeclaredAnnotations(); for(Annotation annotation : annotations){ Class> anType = annotation.annotationType();//拿到Annotation的Class if(anType.getAnnotation(BaseEvent.class)!=null){ method.setAccessible(true); try{ Method valueMethod = anType.getDeclaredMethod("values"); Object values = valueMethod.invoke(annotation); int len = Array.getLength(values); if(len>0){ for(int i=0;i這裡可以拿到自定義method和注解本身。不太了解的可以研究下java的annotation的用法。 由以上的方法的可以實現注解事件的綁定,可以自己定義事件的注解,優雅的開始你的代碼吧!
時候我們需要監聽ScroView的滑動情況,比如滑動了多少距離,是否滑到布局的頂部或者底部。可惜的是SDK並沒有相應的方法,不過倒是提供了一個 復制代碼 代碼如下:pro
android-async-http開源項目可以是我們輕松的獲取網絡數據或者向服務器發送數據,使用起來非常簡單,關於android-async-http開源項目的介紹內容
前言在H5火熱的時代,許多框架都出了底部彈窗的控件,在H5被稱為彈出菜單ActionSheet,今天我們也來模仿一個ios的底部彈窗,取材於蘋果QQ的選擇頭像功能。正文廢
Android -- Camera2(Android5.0) Camera2 Camera2是Android5.0中的其中一個新的特性,新的API。與原來的