首页 > 代码库 > (一)Android使用自定义注解来初始化控件

(一)Android使用自定义注解来初始化控件

 一般情况下我们开发Android应用,初始化控件使用findViewById(),可是一个项目开发完毕,你会发现很多这样的代码,其实是重复的。这个时候你就会发现Java自带的注释(Annotation)是多么的方便了。

      

       一、设计一个ContentView的注释

          因为这个注释我们要运在Activity类上,所以我们要申明@Targrt(ElementType.TYPE)。

   

[java] view plaincopyprint?
  1.  @Target(ElementType.TYPE)  
  2.  @Retention(RetentionPolicy.RUNTIME)  
  3.   
  4.  public @interface ContentView {  
  5.  value();  
  6. }  
  

    二、设计一个ContentWidget的注释

        因为这个注释我们要运在类的成员变量上,所以我们要申明@Targrt(ElementType.FILELD)。类成员变量指定我们申明的控件对象

[java] view plaincopyprint?
  1. @Target(ElementType.FIELD)  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. public @interface ContentWidget {  
  4.     int value();  
  5. }  
  

  三、设计一个工具类来提取并处理上述自定义的Annotation类的信息

  

[java] view plaincopyprint?
  1.      public static void injectObject(Object object, Activity activity) {  
  2.   
  3. Class<?> classType = object.getClass();  
  4.   
  5. // 该类是否存在ContentView类型的注解  
  6. if (classType.isAnnotationPresent(ContentView.class)) {  
  7. // 返回存在的ContentView类型的注解  
  8. ContentView annotation = classType.getAnnotation(ContentView.class);  
  9.   
  10.   
  11. try {  
  12.   
  13.   
  14. // 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。  
  15. Method method = classType  
  16. .getMethod("setContentView"int.class);  
  17. method.setAccessible(true);  
  18. int resId = annotation.value();  
  19. method.invoke(object, resId);  
  20.   
  21.   
  22. catch (NoSuchMethodException e) {  
  23. // TODO Auto-generated catch block  
  24. e.printStackTrace();  
  25. catch (IllegalArgumentException e) {  
  26. // TODO Auto-generated catch block  
  27. e.printStackTrace();  
  28. catch (IllegalAccessException e) {  
  29. // TODO Auto-generated catch block  
  30. e.printStackTrace();  
  31. catch (InvocationTargetException e) {  
  32. // TODO Auto-generated catch block  
  33. e.printStackTrace();  
  34. }  
  35.   
  36.   
  37. }  
  38.   
  39.   
  40. // 返回 Field 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的成员变量,  
  41. // 包括公共、保护、默认(包)访问和私有成员变量,但不包括继承的成员变量。  
  42. Field[] fields = classType.getDeclaredFields();  
  43.   
  44.   
  45. if (null != fields && fields.length > 0) {  
  46.   
  47.   
  48. for (Field field : fields) {  
  49. // 该成员变量是否存在ContentWidget类型的注解  
  50. if (field.isAnnotationPresent(ContentWidget.class)) {  
  51.   
  52.   
  53. ContentWidget annotation = field  
  54. .getAnnotation(ContentWidget.class);  
  55. int viewId = annotation.value();  
  56. View view = activity.findViewById(viewId);  
  57. if (null != view) {  
  58. try {  
  59. field.setAccessible(true);  
  60. field.set(object, view);  
  61. catch (IllegalArgumentException e) {  
  62. // TODO Auto-generated catch block  
  63. e.printStackTrace();  
  64. catch (IllegalAccessException e) {  
  65. // TODO Auto-generated catch block  
  66. e.printStackTrace();  
  67. }  
  68. }  
  69.   
  70.   
  71. }  
  72.   
  73.   
  74. }  
  75.   
  76.   
  77. }  
  78.   
  79.    
  80. }  


    四、在Activity类中我们该怎么使用我们定义的注释

           

[java] view plaincopyprint?
  1. @ContentView(R.layout.activity_main)  
  2. public class MainActivity extends Activity {  
  3.   
  4.     @ContentWidget(R.id.tv)  
  5.     private TextView textView;  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         // setContentView(R.layout.activity_main);  
  11.         ViewUtils.injectObject(thisthis);  
  12.   
  13.         textView.setText("自定义注释");  
  14.     }  
 

虽然前期准备的工作有点多,但后序我们的开发过程中对于加载布局和初始化控件会省事不少,这个对于大型项目来说,尤为重要,磨刀不误砍材工!

  DEMO 地址


     

(一)Android使用自定义注解来初始化控件