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]));
}
}
}