Android IOC 之 注脚绑定控件 以及事件 事例 代码简单注释讲解

Android IOC 之 注解绑定控件 以及事件 事例 代码简单注释讲解


想必开发过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 {};
}


//绑定控件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;

@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();
	        }
	}

	
}