android 布局文件里输入框的值自动转换到类里边,可以增加为空验证

来源:互联网 发布:腾讯数据恢复留言 编辑:程序博客网 时间:2024/05/17 09:37


   android 布局文件里输入框的值自动转换到类里边,不用一个一个去读取在赋值

   

    先看看android遍历view子控件,用回调函数

    

/**     * 遍历所有view     *      * @param viewGroup     */    public void traversalView(ViewGroup viewGroup) {        int count = viewGroup.getChildCount();        for (int i = 0; i < count; i++) {            View view = viewGroup.getChildAt(i);            if (view instanceof ViewGroup) {                traversalView((ViewGroup) view);            } else {                doView(view);            }        }    }     /**     * 处理view     *      * @param view     */    private void doView(View view) {    }

       

一:方法1 遍历所有子view,得到tag反射+泛型去赋值

  private <T> T traversalView(ViewGroup viewGroup,Class<T> _t)    {         try {     T t = _t.newInstance();     traversalViewTemp(viewGroup,t);     return t;      }          catch (Exception e) { System.out.println("自动为类添加值报错:"+e.getMessage());    return null;}       }            private <T> T traversalViewTemp(ViewGroup viewGroup,T t)    {      try {       int count = viewGroup.getChildCount();          for (int i = 0; i < count; i++) {              View view = viewGroup.getChildAt(i);              if (view instanceof ViewGroup) {              traversalViewTemp((ViewGroup) view,t);              } else {                   doView(view,t);              }          }          return t;} catch (Exception e) { System.out.println("自动为类添加值报错:"+e.getMessage());    return null;}            }    private <T> void doView(View view,T t) {          try    {        if(view.getTag()!=null &&!view.getTag().equals(""))    {       String pname = view.getTag().toString();           System.out.println("得到的属性:"+pname);              if(view instanceof EditText) //这里只读EditText,可以根据需求变化           {           EditText ex = (EditText)view;                      if(ex.getText()!=null){          Field f =   t.getClass().getField(pname);            f.setAccessible(true);//忽略访问符private也可以访问             f.set(t,ex.getText().toString());           }           }    }} catch (Exception e) { System.out.println("自动为类添加值报错:"+e);   }     }

ManualAddOil类

public class ManualAddOil {     private String  oil_type;private String  shipname;public String getOil_type() {return oil_type;}public void setOil_type(String oil_type) {this.oil_type = oil_type;}public String getShipname() {return shipname;}public void setShipname(String shipname) {this.shipname = shipname;}}


使用:

ManualAddOil mao = traversalView(manualdatetime,ManualAddOil.class);                System.out.println("自动转化完后值Shipname:"+mao.getShipname()+",Oil_type:"+mao.getOil_type());    


二:方法2 使用类的属性去匹配

遍历所有view可能会比较多,直接用类的属性去找view然后在赋值

    private <T> T traversalView(ViewGroup viewGroup,Class<T> _t)    {         try {        T t = _t.newInstance();             Field[] fids = t.getClass().getDeclaredFields();//所有属性,与访问修饰符无关          for(int i=0;i<fids.length;i++)        {        Field f = fids[i];        f.setAccessible(true);//忽略访问符private也可以访问              String pname = f.getName();//得到属性名            View view = viewGroup.findViewWithTag(pname);            if(view!=null)            {            if(view instanceof EditText) //这里只读EditText,可以根据需求变化            {           EditText ex = (EditText)view;           if(ex.getText()!=null){          f.set(t,ex.getText().toString());           }            }            }        }           return t;      }         catch (Exception e) { System.out.println("自动为类添加值报错:"+e.getMessage());   return null;}       }

使用方法完全一样


三:方法3  使用注解来配置需要转换的字段


1:定义一个注解

import java.lang.annotation.Documented;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.ElementType;import java.lang.annotation.Target;import java.lang.annotation.RetentionPolicy;@Target(ElementType.FIELD)/*目标:用于字段的注解*/  @Retention(RetentionPolicy.RUNTIME)   @Documented   @Inherited  public @interface AutoCAttribute {    boolean isAutoConvert() default false;//是否需要自动转化  }

2:在model上配置使用注解

public class ManualAddOil {     @AutoCAttribute(isAutoConvert=true)  private String  oil_type;//@AutoCAttribute(isAutoConvert=true)  private String  shipname;public String getOil_type() {return oil_type;}public void setOil_type(String oil_type) {this.oil_type = oil_type;}public String getShipname() {return shipname;}public void setShipname(String shipname) {this.shipname = shipname;}}

3:反射转换的时候运用注解
 public <T> T traversalView(ViewGroup viewGroup,Class<T> _t)    {         try {        T t = _t.newInstance();                Field[] fids = t.getClass().getDeclaredFields();//所有属性,与访问修饰符无关          for(int i=0;i<fids.length;i++)        {        Field f = fids[i];        f.setAccessible(true);//忽略访问符private也可以访问          AutoCAttribute an = f.getAnnotation(AutoCAttribute.class);//得到特性        if(an!=null && an.isAutoConvert())        {        BingValue(t,f,viewGroup);        }                }           return t;      }         catch (Exception e) { System.out.println("自动为类添加值报错:"+e.getMessage());   return null;}       }    private <T> void BingValue(T t,Field f,ViewGroup viewGroup) throws IllegalArgumentException, IllegalAccessException    {    String pname = f.getName();//得到属性名        View view = viewGroup.findViewWithTag(pname);        if(view!=null)        {        if(view instanceof EditText) //这里只读EditText,可以根据需求变化        {       EditText ex = (EditText)view;           if(ex.getText()!=null){          f.set(t,ex.getText().toString());           }        }        }    }
    如果有些少数需要绑定隐藏的值的就直接得到,不用自动转换了



四:使用注解来配置需要取的是控件的text还是tag

   因为有些是使用绑定的值

   

  1:定义注解
      

public @interface AutoCAttribute {    boolean isAutoConvert() default true;//是否需要自动转化      boolean isCanNull() default false;//是否能为空      boolean isTagsecond() default false;//是否通过键值对形势的tag取值(原本的tag用来处理映射了)}
  2:处理特性

 if(an.isTagsecond()==true)          {            f.set(t,ex.getTag(R.id.tag_second));          }          else          {             f.set(t,ex.getText().toString());          }
     这里是用得键值对的方式设置tag的


五:为空认证

     有些简单的为空认证我们可以用特性来配置一下那些不能为空,为空了就抛出个异常给个提示不能为空,就不用一个一个去判断了

      

    1:注解增加一个是否进行为空判断字段

@Target(ElementType.FIELD)/*目标:用于字段的注解*/  @Retention(RetentionPolicy.RUNTIME)   @Documented   @Inherited  public @interface AutoCAttribute {    boolean isAutoConvert() default false;//是否需要自动转化      boolean isCanNull() default false;//是否能为空  }
   

   2:自定义一个为空异常

public class NotNullException extends Exception{public NotNullException(String msg)      {          super(msg);      }  } 

     3:增加一个抛出为空异常,使用的时候捕获相应的异常就行了       

  private <T> void BingValue(T t,Field f,ViewGroup viewGroup,AutoCAttribute an) throws IllegalArgumentException, IllegalAccessException, NotNullException    {    String pname = f.getName();//得到属性名        View view = viewGroup.findViewWithTag(pname);        if(view!=null)        {        if((view instanceof EditText)) //这里只读EditText,TextView可以根据需求变化          {       EditText ex = (EditText)view;           if(ex.getText()!=null){          f.set(t,ex.getText().toString());           }           else            {           if(an.isCanNull()==false)           {           throw new NotNullException("你的信息没有填写完整!");           }           }                   }        if((view instanceof TextView))        {                   TextView ex = (TextView)view;            if(ex.getText()!=null){           f.set(t,ex.getText().toString());            }           else           {          if(an.isCanNull()==false)          {          throw new NotNullException("你的信息没有填写完整!");          }          }        }        }    }  




1 0