Android中通过注解代替findViewById方法
来源:互联网 发布:知乎运营模式 编辑:程序博客网 时间:2024/04/29 04:56
这篇文章主要讲解注解实现findViewById的功能,首先我们来熟悉一下在java中怎么定义一个注解和解析一个注解
注解的概念是在jdk5.0中提出来的,在java.lang的包中已经定义了三个注解:Override,Deprecated,SuppressWarningsOverride相信大家非常熟悉,就是表明这个方法是改写了父类的方法
Deprecated表示在新版本的 jdk中已经不建议使用这个方法或者属性
SuppressWarning就是屏蔽掉一些警告
知道了注解的概念后,我们就来自定义注解
注解的定义和接口的接口非常像,在interface的前面多了一个@
1
2
3
4
public
@interface
TestPerson
{
}
千万不能把前面的@符号弄掉了,弄掉了就成了接口的定义了,上面是一个最简单注解的定义,当然注解和类一样,也可以定义属性,如下:
1
2
3
4
5
public
@interface
TestPerson
{
//name既是这个注解的属性,也是注解的方法,调用name()返回值就是name
String name()
default
gavin;
}
我现在想定义两个注解,一个注解用来说明某个类的意义,另一个注解用来说明类中的某个方法由谁测试的,便于追究责任,定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
//用来标注某个类是用来干嘛的
public
@interface
ClassFunction
{
String value()
default
;
}
//用来标注类中的方法是被谁测试的
public
@interface
TestPerson
{
//name是属性而不是方法,gavin是它的默认值,在定义的时候可以不用给定默认值
String name()
default
gavin;
}
那么怎么限定一个注解是用在类上还是用在方法上?比如Override就是用在方法上的注解,Deprecated是既可以用在方法上面,也可以用在类上面,我们直接看看Override是怎么实现的吧
1
2
3
4
5
6
7
8
9
10
@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一下
那么我们就完善我们自己的注解吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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
;
}
那么我们就来使用一下我们的注解吧
1
2
3
4
5
6
7
8
9
10
11
@ClassFunction
(用于描述一个人的基本信息)
public
class
Person
{
private
static
final
String TAG = Person;
@TestPerson
(name=jj)
public
void
setName()
{
}
}
这里要说明一点就是:如果某个注解属性使用value作为名称如ClassFunction中的value,那么赋值的时候可以直接@ClassFunction(用于描述一个人的基本信息),但是如果你使用的是其他名称,那么必须@TestPerson(name=jj)这样调用
以上就是定义一个注解的过程,下面我们来解析一个注解
定义一个TestPerson注解
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 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类中加入注解
1
2
3
4
5
6
7
8
public
class
Person {
private
static
final
String TAG = Person;
@TestPerson
(name=gavin)
public
void
getName()
{
}
}
解析注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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) {
}
}
}</person>
已经将定义注解和解析注解讲解完了,下面来具体分析一下怎么在Android中使用注解来代替findViewById
定义一个注解
1
2
3
4
5
6
7
@Target
(ElementType.FIELD)
@Retention
(RetentionPolicy.RUNTIME)
public
@interface
InjectView
{
//id就是控件id,在某一个控件上使用注解标注其id
int
id()
default
-
1
;
}
在Activity中加入注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
- 自定义注解, 完美代替findViewById()
- 注解Butterknife使用 代替findViewById
- android通过反射代替findViewById的过多使用
- android利用annotation代替findViewById()
- Android使用DataBinding代替findViewById
- Android:注解初始化findViewById
- Android: 使用注解findViewById
- Android 注解findViewById、onClick
- JS同个浏览器,同一个连接只打开一次
- Android通过注解初始化View
- 第五周项目2(2)
- 常用算法-分治法
- PHP在linux上执行外部命令(整理)
- Android中通过注解代替findViewById方法
- 腾讯产品总监曹菲:为何我工作十年,内心仍无比恐慌?
- bzoj 2761: [JLOI2011]不重复数字
- NYOJ-119-士兵杀敌(三)(线段树)
- iOS7使用AFNetworking3.0上传图片时出现的问题
- AndroidAnnotations
- Android工具类——NumberUtils把数字字符串转换成指定国家的货币类型
- Problem B: 结构体---职工信息结构体
- Android开发环境—软件(适用于win7/10 64位)