想必开发过android的都使用过一些 框架,然而框架里都会使用一些,注解来帮助我们,节省大量的代码开发量。同时也使代码更加的简洁。
但是注解是通过java反射来实现的当然可能会牺牲掉一些性能。
以下是本人写的一个较为简单的绑定控件,并且触发其OnclickListem 事件。
//直接先看下注解方法。比较简单,清晰
public class MainActivity extends FragmentActivity {
<span style="white-space:pre"> </span>//绑定对应的按钮控件,事件名称为<span style="font-family: Arial, Helvetica, sans-serif;">onClickCallback</span>
@InjectView(id = R.id.button1, clickMethod = "onClickCallback")
private Button Button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UIBindUtil.bind(this);//初始化绑定
}
@ClickMethod(R.id.button1)
public void onClickCallback(View view) {//触发的事件
Toast.makeText(MainActivity.this, "我是注解", 1).show();
}
}
//接下来是绑定的初始化类
package com.ferris.ioc;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.app.Activity;
public class UIBindUtil {
/**
* 绑定初始化各个空间的属性以及事件
* @param activity
*/
public static void bind(Activity activity) {
Class<?> cl = activity.getClass();
bindViews(activity, cl);
bindMethods(activity, cl);
}
/**
* 为按钮绑定对应的事件方法
* @param activity
* @param cl
*/
private static void bindMethods(Activity activity, Class<?> cl) {
for (Method method : cl.getDeclaredMethods()) {
ClickMethod oc = method.getAnnotation(ClickMethod.class);
if (oc != null) {
int ids[] = oc.value();
for (int id : ids) {
OnEventListener listener = new OnEventListener(activity)
.setmClick(id,method.getName());
activity.findViewById(id).setOnClickListener(listener);
}
}
}
}
/**
* 初始化按钮
* @param activity
* @param cl
*/
private static void bindViews(Activity activity, Class<?> cl) {
try {
for (Field field : cl.getDeclaredFields()) {
InjectView av = field.getAnnotation(InjectView.class);
if (av != null) {
field.setAccessible(true);
setView(field, activity, av.id());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setView(Field view, Activity activity, int id)
throws IllegalArgumentException, IllegalAccessException {
view.set(activity, activity.findViewById(id));
}
}
//点击方法的注入类
package com.ferris.ioc;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ClickMethod {
int[] value() default {};
}
package com.ferris.ioc;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView {
public int id();
public String clickMethod() default ""; // 点击回调方法(方法参数必须只有一个View!)
}
//绑定方法事件触发管理类,管理类比较简单,我简单注释了下。相信看起来容易了
package com.ferris.ioc;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
@SuppressLint("UseSparseArrays")
public class OnEventListener implements OnClickListener{
private Activity activity;
private static Map<Integer, String> listeners = new HashMap<Integer, String>(); //我们保存着控件ID以及方法名称的关联
public OnEventListener(Activity activity) {
// TODO Auto-generated constructor stub
this.activity=activity;
}
public OnEventListener() {
}
public OnEventListener setmClick(Integer id,String name) { //添加关联,并返回监听接口给View进行设置监听
// TODO Auto-generated method stub
listeners.put(id, name);
return this;
}
@Override
public void onClick(View v) { //当有事件触发,则通过id去获取对应的方法,传递参数给方法触发对应的方法。即可
// TODO Auto-generated method stub
if(listeners==null||listeners.size()<=0){
return;
}
String methodName=listeners.get(v.getId());
if(TextUtils.isEmpty(methodName)){
return;
}
try {
//通过类去查找对应的方法以及参数类型
Method callbackMethod = activity.getClass().getDeclaredMethod(methodName, View.class);
callbackMethod.setAccessible(true);
//传递对应的参数过去
callbackMethod.invoke(activity, v);
} catch (Exception e) {
e.printStackTrace();
}
}
}