android 布局文件里输入框的值自动转换到类里边,可以增加为空验证 电脑版发表于:2016/3/11 17:35 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("你的信息没有填写完整!"); } } } } } ```