1.Java反射的知识
2.Java注解的知识
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点我" />
</RelativeLayout>public class MainActivity extends Activity implements OnClickListener {
/**
* 按钮
*/
private Button bt = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 找到按钮
bt = (Button) findViewById(R.id.bt);
// 设置点击事件
bt.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Toast.makeText(this, "点我了", Toast.LENGTH_LONG).show();
}
}
public class MainActivity extends Activity {
/**
* 按钮
*/
@Injection(value = R.id.bt,click = "clickView")
private Button bt = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//让注解起作用
ViewInjectionUtil.injectView(this);
}
public void clickView() {
Toast.makeText(this, "点我了,用了注解框架", Toast.LENGTH_LONG).show();
}
}@Injection(value = R.id.bt,click = "clickView")
//让注解起作用 ViewInjectionUtil.injectView(this);
/**
* 运行时期有效,和针对的是字段
*
* @author xiaojinzi
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Injection {
/**
* 字段对应布局文件的id
*
* @return
*/
int value();
/**
* 点击事件
* @return
*/
String click() default "";
/**
* 长按的点击事件
* @return
*/
String longClick() default "";
}/**
* 对activity中的字段进行注入
*
* @param act
*/
public static void injectView(Activity act) {
// 获取这个activity中的所有字段
Field[] fields = act.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
// 循环拿到每一个字段
Field field = fields[i];
if (field.isAnnotationPresent(Injection.class)) { // 如果这个字段有注入的注解
// 获取注解对象
Injection injection = field.getAnnotation(Injection.class);
int value = injection.value();
field.setAccessible(true); // 即使私有的也可以设置数据
Object view = null;
try {
view = act.findViewById(value);
// 设置字段的属性
field.set(act, view);
} catch (Exception e) {
e.printStackTrace();
L.s(TAG, "注入属性失败:" + field.getClass().getName() + ":" + field.getName());
}
try {
if (view instanceof View) {
View v = (View) view;
// 获取点击事件的触发的方法名称
String methodName = injection.click();
EventListener eventListener = null;
// 如果不是空字符串
if (!"".equals(methodName)) {
eventListener = new EventListener(act);
// 设置点击事件
v.setOnClickListener(eventListener);
eventListener.setClickMethodName(methodName);
}
methodName = injection.longClick();
if (!"".equals(methodName)) {
if (eventListener == null) {
eventListener = new EventListener(act);
}
// 设置点击事件
v.setOnLongClickListener(eventListener);
eventListener.setLongClickMethodName(methodName);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* Created by cxj on 2016/1/21.
*
* @author 小金子
*/
public class EventListener implements View.OnClickListener, View.OnLongClickListener {
/**
* 类的标识
*/
private String tag = "EventListener";
/**
* 设置是否有日志的输出
*/
private boolean isLog = false;
/**
* 反射中要被调用方法的对象,通过构造方法进来
*/
private Object receiver = null;
/**
* 点击事件的方法名字
*/
private String clickMethodName = "";
/**
* 长按事件的方法的名字
*/
private String longClickMethodName = "";
/**
* 设置点击事件的方法名字
*
* @param clickMethodName
*/
public void setClickMethodName(String clickMethodName) {
this.clickMethodName = clickMethodName;
}
/**
* 设置长按的点击事件的方法的名字
*
* @param longClickMethodName
*/
public void setLongClickMethodName(String longClickMethodName) {
this.longClickMethodName = longClickMethodName;
}
/**
* 构造函数
*
* @param receiver
* 控件所在的activity或者Fragment
*/
public EventListener(Object receiver) {
this.receiver = receiver;
}
@Override
public void onClick(View v) {
Method method = null;
try {
method = receiver.getClass().getMethod(clickMethodName);
if (method != null) {
// 调用该方法
method.invoke(receiver);
}
} catch (Exception e) {
if (isLog)
L.s(tag, "寻找无参数列表的方法:" + clickMethodName + "失败");
}
try {
if (method == null) {
method = receiver.getClass().getMethod(clickMethodName, View.class);
if (method != null) {
method.invoke(receiver, v);
}
}
} catch (Exception e) {
if (isLog)
L.s(tag, "寻找带有View类型参数的方法:" + clickMethodName + "失败");
}
}
@Override
public boolean onLongClick(View v) {
Method method = null;
try {
method = receiver.getClass().getMethod(longClickMethodName);
if (method != null) {
// 调用该方法
method.invoke(receiver);
}
} catch (Exception e) {
if (isLog)
L.s(tag, "寻找无参数列表的方法:" + longClickMethodName + "失败");
}
try {
if (method == null) {
method = receiver.getClass().getMethod(longClickMethodName, View.class);
if (method != null) {
method.invoke(receiver, v);
}
}
} catch (Exception e) {
if (isLog)
L.s(tag, "寻找带有View类型参数的方法:" + longClickMethodName + "失败");
}
return true;
}
}
原文:http://blog.csdn.net/u011692041/article/details/51396232