Android 通过 annotation ViewInject

来源:互联网 发布:服装行业利润知乎 编辑:程序博客网 时间:2024/06/04 20:05

前言:

 通常对控件的获取对象是通过sourceView.findViewById(R.id.xx)。通过获取控件的中的注解形式实现一些控件对象。

如:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. @ViewInject(id=R.id.text_title)  
  2. TextView text_title;  
  3.   
  4. @ViewInject(id=R.id.button,click="btnOk")  
  5. Button button;  

1、注解对象创建

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import java.lang.annotation.ElementType;  
  2. import java.lang.annotation.Retention;  
  3. import java.lang.annotation.RetentionPolicy;  
  4. import java.lang.annotation.Target;  
  5.   
  6. @Target(ElementType.FIELD)  
  7. @Retention(RetentionPolicy.RUNTIME)  
  8. public @interface ViewInject {  
  9.     public int id();  
  10.     public String click() default "";  
  11. }  


2、通过反射获取控件对象,并且设置控件对象上面设置的点击事件

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import java.lang.reflect.Field;  
  2. import java.lang.reflect.InvocationTargetException;  
  3. import java.lang.reflect.Method;  
  4. import java.util.EventListener;  
  5.   
  6. import android.app.Activity;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9.   
  10. public class ViewInjectUtil {  
  11.       public static void initViewInject(Activity activity) {  
  12.             initViewInject(activity, activity.getWindow().getDecorView());  
  13.         }  
  14.   
  15.         private static void initViewInject(final Object injectedSourse,  
  16.                                            View sourceView) {  
  17.             Field[] fields = injectedSourse.getClass().getDeclaredFields();  
  18.             if (fields != null && fields.length > 0) {  
  19.                 for (Field field : fields) {  
  20.                     try {  
  21.                         // 设置为true 可以访问属性中的私有变量  
  22.                         field.setAccessible(true);  
  23.                         if (field.get(injectedSourse) != null) {  
  24.                             continue;  
  25.                         }  
  26.                         ViewInject mViewInject = field  
  27.                                 .getAnnotation(ViewInject.class);  
  28.                         if (mViewInject != null) {  
  29.                             int viewId = mViewInject.id();  
  30.                             field.set(injectedSourse,  
  31.                                     sourceView.findViewById(viewId));  
  32.                             Object obj = field.get(injectedSourse);  
  33.                             if (obj instanceof View) {  
  34.                                 setMethodOnClick(obj,injectedSourse,mViewInject.click());  
  35.   
  36.   
  37.                             }  
  38.   
  39.                         }  
  40.   
  41.                     } catch (Exception e) {  
  42.                         // TODO: handle exception  
  43.                     }  
  44.   
  45.                 }  
  46.             }  
  47.   
  48.         }  
  49.   
  50.         private static void setMethodOnClick(Object obj, final Object injectedSourse,String methodName) {  
  51.             final Method method ;  
  52.             try {  
  53.                 method = injectedSourse.getClass()  
  54.                        .getDeclaredMethod(methodName,  
  55.                                View.class);  
  56.                 ((View) obj)  
  57.                         .setOnClickListener(new OnClickListener() {  
  58.   
  59.                             @Override  
  60.                             public void onClick(View v) {  
  61.                                 try {  
  62.                                     method.invoke(injectedSourse, v);  
  63.                                 } catch (IllegalAccessException e) {  
  64.                                     // TODO Auto-generated catch  
  65.                                     // block  
  66.                                     e.printStackTrace();  
  67.                                 } catch (IllegalArgumentException e) {  
  68.                                     // TODO Auto-generated catch  
  69.                                     // block  
  70.                                     e.printStackTrace();  
  71.                                 } catch (InvocationTargetException e) {  
  72.                                     // TODO Auto-generated catch  
  73.                                     // block  
  74.                                     e.printStackTrace();  
  75.                                 }  
  76.                             }  
  77.                         });  
  78.             } catch (NoSuchMethodException e) {  
  79.                 e.printStackTrace();  
  80.             }  
  81.   
  82.         }  
  83. }  

3、Demo演示

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public class MainActivity extends Activity {  
  2.   
  3.     @ViewInject(id=R.id.text_title)  
  4.     TextView text_title;  
  5.       
  6.     @ViewInject(id=R.id.button,click="btnOk")  
  7.     Button button;  
  8.       
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.activity_main);  
  13.         ViewInjectUtil.initViewInject(MainActivity.this);  
  14.           
  15.   
  16.           
  17.     }  
  18.     public void btnOk(View v){  
  19.         text_title.setText("text set form button");  
  20.      }  
  21.   
  22.   
  23. }  

总计:

本节的代码参考了 https://github.com/yangfuhai/afinal 中实现的Code

反射的详细Demo 

参考:http://my.oschina.net/zc741520/blog/195460

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package demo.reflect;  
  2.   
  3. import java.lang.reflect.*;  
  4.   
  5. public class ReflectDemo {  
  6.   
  7.     /** 
  8.      * 为了看清楚Java反射部分代码,所有异常我都最后抛出来给虚拟机处理 
  9.      */  
  10.     public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, NoSuchMethodException {  
  11.   
  12.         System.out.println("demo1:通过Java反射机制得到类的包名和类名");  
  13.         demo1();  
  14.   
  15.         System.out.println("");  
  16.         System.out.println("demo2:验证所有的类都是Class类的实例对象");  
  17.         demo2();  
  18.   
  19.         System.out.println("");  
  20.         System.out.println("demo3:通过Java反射机制,用 Class 创建类对象,这也就是反射存在的意义所在");  
  21.         demo3();  
  22.   
  23.         System.out.println("");  
  24.         System.out.println("demo4:通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象");  
  25.         demo4();  
  26.   
  27.         System.out.println("");  
  28.         System.out.println("demo5:通过Java反射机制操作成员变量, set 和 get");  
  29.         demo5();  
  30.   
  31.         System.out.println("");  
  32.         System.out.println("demo6:通过Java反射机制得到类的一些属性:继承的接口、父类、函数信息、成员信息、类型等");  
  33.         demo6();  
  34.   
  35.         System.out.println("");  
  36.         System.out.println("demo7:通过Java反射机制调用类方法");  
  37.         demo7();  
  38.   
  39.         System.out.println("");  
  40.         System.out.println("demo8:通过Java反射机制得到类加载器信息");  
  41.         demo8();  
  42.     }  
  43.   
  44.     /** 
  45.      * demo1:通过Java反射机制得到类的包名和类名 
  46.      */  
  47.     public static void demo1() {  
  48.         Person person = new Person();  
  49.         System.out.println("包名:" + person.getClass().getPackage().getName());  
  50.         System.out.println("完整类名:" + person.getClass().getName());  
  51.     }  
  52.   
  53.     /** 
  54.      * demo2:验证所有的类都是Class类的实例对象 
  55.      */  
  56.     public static void demo2() throws ClassNotFoundException {  
  57.         //定义两个类型都未知的Class,设置初值为null,看看如何给它们赋值成Person类  
  58.         Class<?> class1 = null;  
  59.         Class<?> class2 = null;  
  60.         //写法1,可能抛出 ClassNotFoundException 异常,多用这个写法  
  61.         class1 = Class.forName("demo.reflect.Person");  
  62.         System.out.println("写法1,包名:" + class1.getPackage().getName() + " , 完整类名:" + class1.getName());  
  63.         //写法2  
  64.         class2 = Person.class;  
  65.         System.out.println("写法2,包名:" + class2.getPackage().getName() + " , 完整类名:" + class2.getName());  
  66.     }  
  67.   
  68.     /** 
  69.      * demo3:通过Java反射机制,用 Class 创建类对象,这也就是反射存在的意义所在 
  70.      */  
  71.     public static void demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException {  
  72.         Class<?> class1 = null;  
  73.         class1 = Class.forName("demo.reflect.Person");  
  74.         //由于这里不能带参数,所以你要实例化的这个类Person,一定要有无参构造函数  
  75.        /* Person person = (Person) class1.newInstance(); 
  76.         person.setName("xiaoming"); 
  77.         person.setAge(20); 
  78.         System.out.println(person.getName() + " , " + person.getAge());*/  
  79.           
  80.         Person person=(Person) Class.forName("demo.reflect.Person").newInstance();  
  81.         person.setAge(30);  
  82.         person.setName("wang");  
  83.         System.out.println(person.getAge()+"  "+person.getName());  
  84.     }  
  85.   
  86.     /**    
  87.      * demo4:通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象 
  88.      */  
  89.     public static void demo4() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {  
  90.         Class<?> class1 = null;  
  91.         Person person1 = null;  
  92.         Person person2 = null;  
  93.   
  94.         class1 = Class.forName("demo.reflect.Person");  
  95.         Constructor<?>[] constructors = class1.getConstructors();  
  96.   
  97.         person1 = (Person) constructors[0].newInstance();  
  98.         person1.setName("xiaoming");  
  99.         person1.setAge(20);  
  100.         System.out.println(person1.getName() + " , " + person1.getAge());  
  101.         person2 = (Person) constructors[1].newInstance(21"xiaohong");  
  102.         System.out.println(person2.getName() + " , " + person2.getAge());  
  103.     }  
  104.   
  105.     /** 
  106.      * demo5:通过Java反射机制操作成员变量, set 和 get 
  107.      */  
  108.     public static void demo5() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, SecurityException {  
  109.         Class<?> class1 = Class.forName("demo.reflect.Person");  
  110.         Object obj = class1.newInstance();  
  111.         Field personNameField = class1.getDeclaredField("name");  
  112.         personNameField.setAccessible(true); //取消访问检查  
  113.         personNameField.set(obj, "小虎");  
  114.         System.out.println("修改属性之后得到属性变量的值:" + personNameField.get(obj));  
  115.     }  
  116.   
  117.     /** 
  118.      * demo6:通过Java反射机制得到类的一些属性:继承的接口、父类、函数信息、成员信息、类型等 
  119.      */  
  120.     public static void demo6() throws ClassNotFoundException {  
  121.         Class<?> class1 = Class.forName("demo.reflect.SuperMan");  
  122.   
  123.         //取得父类名称  
  124.         Class<?> superclass = class1.getSuperclass();  
  125.         System.out.println("SuperMan类的父类名:" + superclass.getName());  
  126.   
  127.         Field[] fields = class1.getDeclaredFields();  
  128.         for (int i = 0; i < fields.length; i++) {  
  129.             System.out.println("类中的成员" + i + ": " + fields[i]);  
  130.         }  
  131.   
  132.         //取得类方法  
  133.         Method[] methods = class1.getDeclaredMethods();  
  134.         for (int i = 0; i < methods.length; i++) {  
  135.             System.out.println("取得SuperMan类的方法" + i + ":");  
  136.             System.out.println("函数名:" + methods[i].getName());  
  137.             System.out.println("函数返回类型:" + methods[i].getReturnType());  
  138.             System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers()));  
  139.             System.out.println("函数代码写法: " + methods[i]);  
  140.         }  
  141.   
  142.         //取得类实现的接口,因为接口类也属于Class,所以得到接口中的方法也是一样的方法得到哈  
  143.         Class<?> interfaces[] = class1.getInterfaces();  
  144.         for (int i = 0; i < interfaces.length; i++) {  
  145.             System.out.println("实现的接口类名: " + interfaces[i].getName());  
  146.         }  
  147.     }  
  148.   
  149.     /** 
  150.      * demo7:通过Java反射机制调用类方法 
  151.      */  
  152.     public static void demo7() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {  
  153.         Class<?> class1 = Class.forName("demo.reflect.SuperMan");  
  154.   
  155.         System.out.println("调用无参方法fly():");  
  156.         Method method = class1.getMethod("fly");  
  157.         method.invoke(class1.newInstance());  
  158.   
  159.         System.out.println("调用有参方法walk(int m):");  
  160.         method = class1.getMethod("walk"int.class);  
  161.         method.invoke(class1.newInstance(), 100);  
  162.     }  
  163.   
  164.     /** 
  165.      * demo8:通过Java反射机制得到类加载器信息 
  166.      * 在java中有三种类类加载器 
  167.      * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 
  168.      * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类 
  169.      * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器,同时也是java中默认的加载器。 
  170.      */  
  171.     public static void demo8() throws ClassNotFoundException {  
  172.         Class<?> class1 = Class.forName("demo.reflect.SuperMan");  
  173.         String name = class1.getClassLoader().getClass().getName();  
  174.         System.out.println("类加载器类名:" + name);  
  175.     }  
  176.   
  177. }  
  178.   
  179. class Person {  
  180.     private int age;  
  181.     private String name;  
  182.   
  183.     public Person() {  
  184.   
  185.     }  
  186.   
  187.     public Person(int age, String name) {  
  188.         this.age = age;  
  189.         this.name = name;  
  190.     }  
  191.   
  192.     public int getAge() {  
  193.         return age;  
  194.     }  
  195.   
  196.     public void setAge(int age) {  
  197.         this.age = age;  
  198.     }  
  199.   
  200.     public String getName() {  
  201.         return name;  
  202.     }  
  203.   
  204.     public void setName(String name) {  
  205.         this.name = name;  
  206.     }  
  207. }  
  208.   
  209. interface ActionInterface {  
  210.     public void walk(int m);  
  211. }  
  212.   
  213. class SuperMan extends Person implements ActionInterface {  
  214.     private boolean blueBriefs;  
  215.   
  216.     public void fly() {  
  217.         System.out.println("超人会飞耶~~");  
  218.     }  
  219.   
  220.     public boolean isBlueBriefs() {  
  221.         return blueBriefs;  
  222.     }  
  223.   
  224.     public void setBlueBriefs(boolean blueBriefs) {  
  225.         this.blueBriefs = blueBriefs;  
  226.     }  
  227.   
  228.     @Override  
  229.     public void walk(int m) {  
  230.         System.out.println("超人会走耶~~走了" + m + "米就走不动了!");  
  231.     }  
  232. }  
0 0
原创粉丝点击