編輯:關於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的用法。
由以上的方法的可以實現注解事件的綁定,可以自己定義事件的注解,優雅的開始你的代碼吧!
Android中實現監聽ScrollView滑動事件
時候我們需要監聽ScroView的滑動情況,比如滑動了多少距離,是否滑到布局的頂部或者底部。可惜的是SDK並沒有相應的方法,不過倒是提供了一個 復制代碼 代碼如下:pro
08_android入門_android-async-http開源項目介紹及使用方法
android-async-http開源項目可以是我們輕松的獲取網絡數據或者向服務器發送數據,使用起來非常簡單,關於android-async-http開源項目的介紹內容
Android控件PopupWindow模仿ios底部彈窗
前言在H5火熱的時代,許多框架都出了底部彈窗的控件,在H5被稱為彈出菜單ActionSheet,今天我們也來模仿一個ios的底部彈窗,取材於蘋果QQ的選擇頭像功能。正文廢
Android -- Camera2(Android5.0)
Android -- Camera2(Android5.0) Camera2 Camera2是Android5.0中的其中一個新的特性,新的API。與原來的