http://blog.csdn.net/blog_wang/article/details/38468547
FinalActivity
android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。
public class FinalActivityDemo extends FinalActivity { //这里的ViewInject就是下面自定义的注解,id和click都是里面定义的方法 @ViewInject(id = R.id.btn_ok, click="btnOnClick") Button button @ViewInject(id = R.id.tv_show) TextView textView protected void onCreate() { super.onCreate(); setContentView(R.layout.activity_main) } private void btnOnClick() { textView.setText("dkelk") } }
我们看看FinalActivity的部分源码:
protected void onCreate() { super.onCreate(); } public void setContentView(int layoutResourceId) { super.setContentView(layoutResourceId); //初始化指定View中的注入属性,它是在setContentView之后开始绑定的 FinalActivity.initInjectedView(this); }
在介绍initInjectedView之前先了解什么是注释。
例如:@ovverides:这是内置注解,我们复写方法会自动添加。
@ViewInject:自定义注解,FinalActivity的注解就在这里,然后上面类就可以用了。
@Interface是java中表示声明一个注解类的关键词。
ElementType和RententionPolicy是2个枚举类
ElementType: METHOD:方法声明(表示注解是作用在方法上),FIELD:字段声明(表示作用在属性 上,如上面的Button button),PACKAGE(包声明)等的
RententionPolicy:RUNNTIME和CLASS,编译器都会将注释记录在类文件中,但RUNNTIME是在程序 运行时VM会保留注释,所以可以通过反射获取到,CLASS就不行。SOURCE是编译器丢弃的注释。
@Target(ElementType.FIELD) //表明注解的是一个字段,如Button button字段,而不是函数等。 @Retention(RententionPolicy.RUNTIME) //表明该注解保存在class字节中可以在运行时获取到 public @interface ViewInject { public int id(); public String click() default ""; public String longClick() default ""; public String itemClick() default ""; public String itemLongClick() default ""; public Select select() default @Select(selected=""); }
现在我们来看看FinalActivity.initInjectedView(this);
public static void initInjectedView(Activity sourceActivity) { initInjectedView(sourceActivity, sourceActivity.getWindow().getDecorView()); } public static void initInjectedView(Object injectedSource, View sourceView) { //通过反射获取activity的所有方法,并过滤出 Field[] fields = injectedSource.getClass().getDeclaredFields(); if (fileds != null && fields.length > 0) { for (Field field : fields) { ViewInject viewInject = field.getAnnonation(ViewInject.class); if (viewInject != null) { //这里获取的就是我们定义的@ViewInject(id=R.id.btn_click) int viewId = viewInject.id(); try { field.setAccessible(true); field.set(injectedSource, sourceView.findViewById(viewId)); } catch (Exception e) { e.printStackTrace(); } //这里获取的就是我们定义的@ViewInject(click="btnOnClick"),像id(),Click()等方法都是在public @interface ViewInject{}中定义的 String clickMethod = viewInject.click(); if (!TextUtils.isEmpty(clickMethod)) setViewClickListener(injectedSource, clickMethod); String longClickMethod = viewInject.longClick(); if (!TextUtils.isEmpty(longClickMethod)) setViewLongClickListener(injectedSource, field, longClickMethod); String itemClickMethod = viewInject.itemClick(); if (!TextUtils.isEmpty(itemClickMethod)) setItemClickListener(injectedSource, field, itemClickMethod); String itemLongClickMethod = viewInject.itemLongClick(); if (!TextUtils.isEmpty(longClickMethod)) setViewLongClickListener(injectedSource, field, itemLongClickMethod); Select select = viewInject.select(); if(!TextUtils.isEmpty(select.selected()) setViewSelectLisstener(injectedSource, field, select.selected, select.noSelect()); }}}}
//下面是为view绑定onClick事件:setViewClickListener(injectedSource,field,clickMethod);同样是反射。EventListener暂时就不写了。
private static void setViewClickListener(Object injectedSource,Field field, String clickMethod) { try { Object obj = field.get(injectedSource); if (obj instanceOf View) { ((View)obj).setOnClickListener(new EventListener(injectedSource).click(clickMethod)); } } catch(Exception e) { e.printStackTrace(); } }