用注解来省略findViewById

来源:互联网 发布:java游戏移植官网 编辑:程序博客网 时间:2024/06/09 21:53

在写项目的时候,在引入XUtils后,有一个类ViewUtils,在Activity加入ViewUtils.inject(this),就可以直接View及其子类加上注解就可以省略多行findViewById的操作.

本文是仿这个使用的代码实现,共两个类几十行代码,注释我放入到代码里微笑

第一个注解类:ViewInject,为的是成员变量与资源ID有所关联,代码如下:

import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)//表示是在成员变量上使用public @interface ViewInject {    int value() default -1;}第二个工具类:ViewUtil,提供inject方法,代码如下:
import android.app.Activity;import android.view.View;import com.midas.viewinject.annotation.ViewInject;//改成相应的包名import java.lang.reflect.Field;public class ViewUtil {    public static void inject(Activity activity) {        //遍历activity里成员变量 用getFields不能获取private成员     Field[] fields = activity.getClass().getDeclaredFields();        for (Field field : fields) {            //筛选 对合适的条件(Viewject的注解值和View的子类) 进行findViewByID的操作       ViewInject annotation = field.getAnnotation(ViewInject.class);             /* Class.isAssignableFrom()是用来判断一个类Class1和另一个类Class2是否相同或是另一个类Class2的父类或接口。            格式为:Class1.isAssignableFrom(Class2)*/            int resID = -1;//??? 此处有点小问题:资源id是自动生成,其取值范围为多少?是否可能为-1?            if (View.class.isAssignableFrom(field.getType()) && annotation != null && (resID = annotation.value()) != -1) {                //暴力反射,为的是能给privatefield也能赋值         if (!field.isAccessible())                    field.setAccessible(true);                //field对应的对象赋值         try {                    field.set(activity, activity.findViewById(resID));                } catch (IllegalAccessException e) {                    //这里异常最有可能就是类型传换失败,最好在此用Log进行捕捉           e.printStackTrace();                }            }        }    }}在Activity中的使用此方法的例子,代码片段如下:
public class MainActivity extends AppCompatActivity {    @ViewInject(R.id.tv_show)    private TextView tv_show;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ViewUtil.inject(this);        tv_show.setText("调用反射成功");    }}

此文主要提供一种实现思路,在上述代码有不完善之处还请指正,另希望有人此答疑:资源ID(也就是R.id.xxx)取值范围为多少?


0 0
原创粉丝点击