Android 注解,实现动态绑定view

来源:互联网 发布:软件开发服务费 编辑:程序博客网 时间:2024/05/20 16:32

之前的一篇文章介绍了什么是注解 (直达链接:点击打开链接)


现在有许多开源的注解框架,比如:butterknife/androidannotation等,这些框架能帮助我们大大简化了代码,使我们不用再机械的写这种findViewById,setOnClickListener等方法


接下来就自己用注解,实现了一下view的绑定


1.声明注解 

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface EActivity {    int value();}

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface ViewById {    int value();}

2.在activity中使用注解 

@EActivity(R.layout.activity_annotation) //绑定布局文件public class AnnotationActivity extends AppCompatActivity implements View.OnClickListener {    @ViewById(R.id.text)    private TextView mTextView;    @ViewById(R.id.button)    private Button mButton;    private int mClickTimes = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //调用注解工具类实现对view的绑定        AndroidBindViewUtils.startBinding(this);        mButton.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.button:                mClickTimes++;                mTextView.setText("点击了btn " + mClickTimes + " 次!");                break;        }    }}

3.如何实现view的绑定

 这里用的是运行时注解,需要借助反射的方式获取到具体的方法,然后和对应的值进行绑定

 

public class AndroidBindViewUtils {    private static Method sMethodSetContentView;    private static Method sMethodFindViewById;    public static void startBinding(Activity activity) {        bindContentView(activity);        bindViewById(activity);    }    private static void bindContentView(Activity activity) {        EActivity eActivity = activity.getClass().getAnnotation(EActivity.class);        if (eActivity != null) {            int contentviewId = eActivity.value(); //拿到绑定的layout id            if (sMethodSetContentView == null) {                getSetContentViewMethod();            }            try {                sMethodSetContentView.invoke(activity, contentviewId); //通过反射调用activity的setContentView方法            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }        }    }    private static void bindViewById(Activity activity) {        Field[] fields = activity.getClass().getDeclaredFields();//拿到activity的所有变量        for (Field field : fields) {            ViewById viewById = field.getAnnotation(ViewById.class);//通过变量拿到ViewById注解            if (viewById != null) {                int id = viewById.value();//拿到具体的view id                try {                    if (sMethodFindViewById == null) {                        getFindViewByIdMethod();                    }                    Object view = sMethodFindViewById.invoke(activity, id); //通过反射findViewById获取具体的view                    field.setAccessible(true);                    field.set(activity, view);//把这个view赋值给field变量                } catch (IllegalAccessException e) {                    e.printStackTrace();                } catch (InvocationTargetException e) {                    e.printStackTrace();                }            }        }    }    private static void getSetContentViewMethod() {        if (sMethodSetContentView == null) {            try {                sMethodSetContentView = Activity.class.getDeclaredMethod("setContentView", int.class);                sMethodSetContentView.setAccessible(true);            } catch (NoSuchMethodException e) {                e.printStackTrace();            }        }    }    private static void getFindViewByIdMethod() {        if (sMethodFindViewById == null) {            try {                sMethodFindViewById = Activity.class.getDeclaredMethod("findViewById", int.class);                sMethodFindViewById.setAccessible(true);            } catch (NoSuchMethodException e) {                e.printStackTrace();            }        }    }}

阅读全文
0 0
原创粉丝点击