android实现UI控件自动注入到Activity

       在写android程序里要获取UI控件,我们都必须在Activity通过findViewById()来获取各个UI控件。当然有很多第三方的框架都帮我们简化了这个操作(具体的不在这里介绍了),但本人都觉得还不够简单。因此决定自己写一个控件自动注入。

       在android里,所有在layout里画出的控件你都可以定义一个唯一的ID。
       



       
       然而所有的控件ID都会自动生成在android的R.java文件里。

  public final class R {
   public static final class id {
     public static final int screenPic=0x7f080021;
   }
  }



这样我们就可以开始实现自动注入了,但前提有一个约定,即:Activity中的控件变量名必须与UI里面定义的ID一致。
我们可以先定义一个Activity的抽象类,在里面通过一段静态代码块来将R文件里的控件ID信息保存在内存中。

public abstract class PActivity extends Activity{
 static{
  Class rzz = R.id.class;
                //将所有的控件ID存放在内存中
  for(Field f : rzz.getDeclaredFields()){ 
                    PActivity.cacheMap.put(f.getName(), f);
                }
        }
  //cacheMap保存R.id里面的所有ID信息
  public static final Map cacheMap = new HashMap();
}


接着我们可以重写onCreate方法

    @Override
 protected final void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  try {
   initUI();
   init();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
    //用java反射来实现控件的自动注入
    private void initUI() throws Exception{
  Class clzz = this.getClass();
  Field[] fields = clzz.getDeclaredFields();
  for(Field f : fields){
   int v = r(f.getName());
   if(v!=0){
    Object obj = this.findViewById(v);//控件自动注入
    if(obj!=null){
     f.setAccessible(true);
     f.set(this,obj);
    }
   }
  }
 }

    abstract protected void init() throws Exception;


现在我们来实际写一个Activity来看看实际的效果吧。

public abstract class TestActivity extends PActivity{
 private ImageView screenPic;
 
 //替代onCreate方法
 @Override
 protected void init() {
  //这里就可以直接使用screenPic
  System.out.println(screenPic);
 }
 @Override
 protected int getLayout() {
  // TODO Auto-generated method stub
  return R.layout.main_init;
 }
}







你可能感兴趣的:(android;)