android---------Android中通过注解代替findViewById方法
来源:互联网 发布:杨震"四知"文言文翻译 编辑:程序博客网 时间:2024/04/29 13:26
原文地址:http://www.2cto.com/kf/201405/302998.html
这篇文章主要讲解注解实现findViewById的功能,首先我们来熟悉一下在java中怎么定义一个注解和解析一个注解
注解的概念是在jdk5.0中提出来的,在java.lang的包中已经定义了三个注解:Override,Deprecated,SuppressWarningsOverride相信大家非常熟悉,就是表明这个方法是改写了父类的方法
Deprecated表示在新版本的 jdk中已经不建议使用这个方法或者属性
SuppressWarning就是屏蔽掉一些警告
知道了注解的概念后,我们就来自定义注解
注解的定义和接口的接口非常像,在interface的前面多了一个@
public @interface TestPerson{ }
千万不能把前面的@符号弄掉了,弄掉了就成了接口的定义了,上面是一个最简单注解的定义,当然注解和类一样,也可以定义属性,如下:
public @interface TestPerson{ //name既是这个注解的属性,也是注解的方法,调用name()返回值就是name String name() default gavin;}
我现在想定义两个注解,一个注解用来说明某个类的意义,另一个注解用来说明类中的某个方法由谁测试的,便于追究责任,定义如下:
//用来标注某个类是用来干嘛的public @interface ClassFunction{ String value() default ;} //用来标注类中的方法是被谁测试的public @interface TestPerson{ //name是属性而不是方法,gavin是它的默认值,在定义的时候可以不用给定默认值 String name() default gavin;}
那么怎么限定一个注解是用在类上还是用在方法上?比如Override就是用在方法上的注解,Deprecated是既可以用在方法上面,也可以用在类上面,我们直接看看Override是怎么实现的吧
@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {} @Documented@Retention(RetentionPolicy.RUNTIME)@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})public @interface Deprecated {}
我们发现这两个注解在定义的过程中都使用了其他的注解,像Target和Retention这种注解叫做元注解,我们分别看看它们的意思吧
Target注解的功能就是表明你这个注解是用在什么地方的,它的值是一个枚举型
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
Retention注解的功能差不多说明的就是你的注解的生命周期吧,就是什么时候失效,它的值如下
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
我就介绍这两个元注解吧,其他的感觉也用的不是很多,如果你感兴趣可以自己Google一下
那么我们就完善我们自己的注解吧
@Target(ElementType.METHOD)//作用于方法@Retention(RetentionPolicy.RUNTIME)//在运行时有效(即运行时保留)public @interface TestPerson{ //name是属性而不是方法,gavin是它的默认值,在定义的时候可以不用给定默认值 String name() default gavin;} @Target(ElementType.TYPE)//作用于类上@Retention(RetentionPolicy.RUNTIME)//在运行时有效(即运行时保留)public @interface ClassFunction{ String value() default ;}
那么我们就来使用一下我们的注解吧
@ClassFunction(用于描述一个人的基本信息)public class Person{ private static final String TAG = Person; @TestPerson(name=jj) public void setName() { }}
这里要说明一点就是:如果某个注解属性使用value作为名称如ClassFunction中的value,那么赋值的时候可以直接@ClassFunction(用于描述一个人的基本信息),但是如果你使用的是其他名称,那么必须@TestPerson(name=jj)这样调用
以上就是定义一个注解的过程,下面我们来解析一个注解
定义一个TestPerson注解
/** * com.annotation.TestPerson * @author yuanzeyao * create at 2014年5月21日 下午1:30:14 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface TestPerson { String name();}
然后再Person类中加入注解
public class Person { private static final String TAG = Person; @TestPerson(name=gavin) public void getName() { }}
解析注解
public class Main { private static final String TAG = Main; public static void main(String[] args) { Person person=new Person(); //获得Person对应的Class Class<person> clazz=Person.class; try { //找到getName方法 Method method=clazz.getMethod(getName,null); //判断是否被TestPerson标注 if(method.isAnnotationPresent(TestPerson.class)) { //调用getName方法 method.invoke(person, null); //得到TestPerson注解的实例 TestPerson test=method.getAnnotation(TestPerson.class); //获得其name属性 String name=test.name(); System.out.println(this method is test by-->+name); } } catch (SecurityException e) { } catch (NoSuchMethodException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } }}
已经将定义注解和解析注解讲解完了,下面来具体分析一下怎么在Android中使用注解来代替findViewById
定义一个注解
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface InjectView { //id就是控件id,在某一个控件上使用注解标注其id int id() default -1;}
在Activity中加入注解
public class MainActivity extends Activity { public static final String TAG=MainActivity; //标注TextView的id @InjectView(id=R.id.tv_img) private TextView mText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { autoInjectAllField(this); } catch (IllegalAccessException e) { } catch (IllegalArgumentException e) { } if(mText!=null) mText.setText(Hello Gavin); } public void autoInjectAllField(Activity activity) throws IllegalAccessException, IllegalArgumentException { //得到Activity对应的Class Class clazz=this.getClass(); //得到该Activity的所有字段 Field []fields=clazz.getDeclaredFields(); Log.v(TAG, fields size-->+fields.length); for(Field field :fields) { //判断字段是否标注InjectView if(field.isAnnotationPresent(InjectView.class)) { Log.v(TAG, is injectView); //如果标注了,就获得它的id InjectView inject=field.getAnnotation(InjectView.class); int id=inject.id(); Log.v(TAG, id--->+id); if(id>0) { //反射访问私有成员,必须加上这句 field.setAccessible(true); //然后对这个属性复制 field.set(activity, activity.findViewById(id)); } } } } }
0 0
- Android中通过注解代替findViewById方法
- Android中通过注解代替findViewById方法
- Android中通过注解代替findViewById方法
- Android中通过注解代替findViewById方法
- Android中注解详解,通过注解代替findViewById方法
- android---------Android中通过注解代替findViewById方法
- Android中通过注解代替findViewById方法 Android 中的 IOC 框架 【ViewInject】
- 安卓通过注解+反射简单实现代替findViewById方法
- android通过注解实现findViewById 和 setOnClickListener
- 通过JAVA注解简化android的findViewById
- android通过反射代替findViewById的过多使用
- android利用annotation代替findViewById()
- Android使用DataBinding代替findViewById
- Android:注解初始化findViewById
- Android: 使用注解findViewById
- Android 注解findViewById、onClick
- Android进阶-分页与分批及XUtils的注解来代替findViewById
- Android中注解和反射的结合findViewById
- cocos2d-x TestLua 之 CCMenuItemLabel CCMenuItemSprite CCMenuItemFont 菜单类
- Tomcat 工作原理
- Apache Camel rest实现重定向
- ios触摸事件一 :UIEvent
- 数据结构实验之查找六:顺序查找
- android---------Android中通过注解代替findViewById方法
- App在iOS9上不能分享至微信,提示微信没有安装
- 数据库索引
- s从数组中删除指定值(不是指定位置)的元素
- UIScrollView的常用属性
- 分布式系统中 Unique ID 的生成方法
- ifstream ofstream 读写文件异常
- 深入浅出机器学习之支持向量机SVM(SMO算法)
- 深入浅出UML类图