Android中实现自动生成布局View的初始化代码方法
在android开发过程中,界面布局是及其重要的,但同时也是复杂。有的时候我们急于实际运行查看布局效果。但是android的编译速度我实在不想吐槽啥,尤其在布局越来越复杂,项目越来越大,资源文件越来越多的情况下。
尤其是是android的view的初始化,findViewbyId完全是体力活,我们完全可以根据布局文件自动生成View的初始化代码。
首先声明:
1.这是及其容易做到的,实用性性一般,但是在复杂布局和首次写初始化View代码的时候及其好用。
2.只能生成有id标签的view的初始化代码。
思路
其实很简单,就是解析layout布局文件,把有id属性的标签的一些信息(标签类型,id名称等)存起来,然后根据这些信息生成固定的代码。
实现
直接上代码,首先是对layout文件的解析,把解析出来的信息放在一个list中
publicclassSaxHanderextendsDefaultHandler{ privateList<IdNamePair>map=newArrayList<IdNamePair>(); @Override publicvoidstartDocument()throwsSAXException{ super.startDocument(); map.clear(); } @Override publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes)throwsSAXException{ super.startElement(uri,localName,qName,attributes); // System.out.println("-------------------------------------"); Stringtempid=attributes.getValue("id"); Stringid=null; if(tempid!=null){ String[]ss=tempid.split("/"); if(ss!=null&&ss.length==2){ id=ss[1]; } } if(id!=null){ map.add(newIdNamePair(id,qName)); } // System.out.println(id); // System.out.println(qName); } publicList<IdNamePair>getRes(){ returnmap; } }
publicclassIdNamePair{ privateString id; privateStringname; /** *@paramid *@paramname */ publicIdNamePair(Stringid,Stringname){ super(); this.id=id; this.name=name; } publicStringgetId(){ returnid; } publicvoidsetId(Stringid){ this.id=id; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } }
然后一点点的拼接代码
publicclassViewCodeUtil{ staticSAXParserFactorysaxfac=SAXParserFactory.newInstance(); staticSaxHandermySax=newSaxHander(); publicstaticStringgetCode(StringresFileName){ Filef=newFile(resFileName); if(!f.exists()){ returnnull; } try{ saxfac.newSAXParser().parse(f,mySax); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); returnnull; } List<IdNamePair>res=mySax.getRes(); StringBuildersb=newStringBuilder(); StringBuildersb1=newStringBuilder(); sb.append("//----------开始定义域--------------\n"); sb1.append("//----------开始initView方法------------------\n"); sb1.append("publicvoidinitView(){\n"); for(IdNamePairidNamePair:res){ sb.append("private"+idNamePair.getName()+" "+idNamePair.getId()+idNamePair.getName()+";\n"); sb1.append(" "+idNamePair.getId()+idNamePair.getName()+"=("+idNamePair.getName()+")findViewById(R.id."+idNamePair.getId()+");\n"); } sb1.append("}\n"); // System.out.println(sb.toString()); // System.out.println(sb1.toString()); returnsb.append(sb1.toString()).toString(); }
最后是测试类main方法。
publicclassTest{ privatestaticfinalString[]layoutFiles={"./res/g_ruler.xml","./res/report.xml"}; publicstaticvoidmain(String[]args){ if(args!=null){ for(inti=0;i<args.length;i++){ System.out.println(""); System.out.println("---------"+args[i]+"----------"); System.out.println(ViewCodeUtil.getCode(args[i])); } } for(inti=0;i<layoutFiles.length;i++){ System.out.println(""); System.out.println("//---------"+layoutFiles[i]+"----------"); System.out.println(ViewCodeUtil.getCode(layoutFiles[i])); } } }