您的位置:首页 > 其它

Afinal的FinalActivity的注解学习笔记

2015-07-15 16:38 295 查看
在Afinal的FinalActivity中可以用注解开给控件对象赋值和设置监听事件,下面是我的一些学习笔记。

下面是应用的实例:

public class MainActivity extends InjectActivity {
@ViewInject(id = R.id.editText1)EditText et;//应用注解
@ViewInject(id = R.id.button1, click = "onClick")Button btn;//应用注解</span>

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// et = (EditText) findViewById(R.id.editText1);可以省略

}

public void onClick(View v) {
et.setText("ok");

}
}
下面是自定义的注解:

package com.iotek.webservicedemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 自定义的注解
*
*
* Java中提供了四种元注解,专门负责注解其他的注解,分别如下
*
* @Retention元注解,表示需要在什么级别保存该注释信息(生命周期)。
* 可选的RetentionPoicy参数包括:
* RetentionPolicy.SOURCE: 停留在java源文件, 编译器被丢掉
* RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认)
* RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,
*                         因此可以通过反射机制读取注解的信息
* @Target元注解,默认值为任何元素,表示该注解用于什么地方。
* 可用的ElementType参数包括:
* ElementType.CONSTRUCTOR:构造器声明
* ElementType.FIELD:成员变量、对象、属性(包括enum实例)
* ElementType.LOCAL_VARIABLE: 局部变量声明
* ElementType.METHOD: 方法声明
* ElementType.PACKAGE: 包声明
* ElementType.PARAMETER:参数声明
* ElementType.TYPE:类、接口或enum声明
* ElementType.ANNOTATION_TYPE,注解类型
* @Documented 将注解包含在JavaDoc中
* @Inheried 允许子类继承父类中的注解
* @author yang
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
public int id();

public String click() default "";
}
下面是仿照FinalActivity写的一个实例

package com.iotek.webservicedemo;

import java.lang.reflect.Field;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
/**
* 自定义的一个activity 可以用注解来给控件对象赋值和设置监听
* @author yang
*
*/
public class InjectActivity extends Activity {
private static final String TAG = "InjectActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);

InjectActivity.initInjectView(this);
}

@Override
public void setContentView(View view) {
super.setContentView(view);
InjectActivity.initInjectView(this);
}

@Override
public void setContentView(View view, LayoutParams params) {
super.setContentView(view, params);
InjectActivity.initInjectView(this);
}
/**
* 该方法一定要放到setContentView之后执行
* @param activity
*/
public static void initInjectView(Activity activity) {
//  decorView是window中的最顶层view,可以从window中获取到decorView,
// 然后decorView有个getWindowVisibleDisplayFrame方法可以获取到程序显示的区域,
// 包括标题栏,但不包括状态栏。
InjectActivity.initInjectView(activity, activity.getWindow()
.getDecorView());
}
/**
*  通过反射来给对象赋值和设置监听事件
* @param object activity对象
* @param view 用来通过id获取xml文件当中的view对象(view.findViewById(id))
*/
public static void initInjectView(Object object, View view) {
//要用getDeclaredFields()方法获取所有属性字段
Field[] fields = object.getClass().getDeclaredFields();
Log.i(TAG, object.getClass().getName());
if (fields != null && fields.length > 0) {
for (Field field : fields) {
//获取属性的注解
ViewInject inject = field.getAnnotation(ViewInject.class);
if (inject != null) {
//获取注解的id值
int id = inject.id();
Log.i(TAG, field.getName() + "===" + id);
try {
//允许对私有属性更改
field.setAccessible(true);
// 给field赋值
field.set(object, view.findViewById(id));
} catch (Exception e) {
e.printStackTrace();
}
//获取注解的click值就是自己定义的点击方法
String nameString = inject.click();
if (!TextUtils.isEmpty(nameString)) {
try {
//获取field的值(变量的值)
Object obj = field.get(object);
if (obj instanceof View) {
((View) obj)
.setOnClickListener(new EventListener(
object).click(nameString));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
}
下面是EventListener这个类

package com.iotek.webservicedemo;

import java.lang.reflect.Method;

import android.view.View;
import android.view.View.OnClickListener;

public class EventListener implements OnClickListener {
private Object handler;//执行自定义方法方法的对象
private String clickMethod;//自定义方法名

public EventListener(Object handler) {
super();
this.handler = handler;
}

/**
*
* @param method
*            方法名
* @return
*/
public EventListener click(String method) {

this.clickMethod = method;
return this;

}

@Override
public void onClick(View v) {
invokeClickMethod(handler, clickMethod, v);
}
/**
* 用来执行自定义的方法
* @param o 执行自定义方法方法的对象
* @param methodName 自定义方法名
* @param parems 自定义方法 的参数(View v)
* @return Object
*/
public static Object invokeClickMethod(Object o, String methodName,
Object... parems) {
if (o == null) {
return null;
}
Method method = null;
try {
//通过反射获取指定方法名的Method对象
method = o.getClass().getDeclaredMethod(methodName, View.class);
if (method != null) {
//执行方法
return method.invoke(o, parems);
} else {
throw new ClickNotFindException("方法没有找到!" + methodName);
}
} catch (Exception e) {

e.printStackTrace();
}
return null;

}
}


下面是ClickNotFindException类

package com.iotek.webservicedemo;

public class ClickNotFindException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1L;
private String msg;

public ClickNotFindException(String msg) {
super();
this.msg = msg;
}

@Override
public void printStackTrace() {
if (msg != null) {
System.err.println(msg);
}
super.printStackTrace();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: