Android中Layout转成Java代码

android中总是要给控件指定一个id,然后还要在代码中写一个控件名称,两者要对应起来,这个工作本身就是体力劳动。这里我自己写了一个小的代码生成工具类,将anroid的xml布局文件生成为java文件,通过控制台输出。同时支持findViewById模式的,和xutils模式的。xml的解析使用到了pull解析器。demo中已包含jar文件了。举个例子:

假设有这样一个布局文件名字叫做empty.xml



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/empty"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center">
    <ProgressBar android:id="@+id/loading_pb"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 style="@android:style/Widget.ProgressBar.Small.Inverse"/>
    <TextView android:id="@+id/tv_loading"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_toRightOf="@+id/loading_pb"
              android:text="加载中..."/>
LinearLayout>

通过我的工具类XMLGen.java,直接输出依据id生成的控件名称。从控制台copy一下到代码中就行了。

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * 传入一个xml字符串,转换成
 */
public class XMLGen {

    private static String xml = "\n"
            + "\n"
            + "
            + "              android:id=\"@+id/empty\"\n"
            + "              android:layout_width=\"match_parent\"\n"
            + "              android:layout_height=\"match_parent\"\n"
            + "              android:gravity=\"center\">\n"
            + "    
            + "                 android:layout_width=\"wrap_content\"\n"
            + "                 android:layout_height=\"wrap_content\"\n"
            + "                 style=\"@android:style/Widget.ProgressBar.Small.Inverse\"/>\n"
            + "    
            + "              android:layout_width=\"wrap_content\"\n"
            + "              android:layout_height=\"wrap_content\"\n"
            + "              android:layout_toRightOf=\"@+id/loading_pb\"\n"
            + "              android:text=\"加载中...\"/>\n" + "";

    private static String xmlpath = "empty.xml";

    private static String viewInject = "@ViewInject(R.id.%s)\n";
    private static String findViewById = "%s = (%s) %sfindViewById(R.id.%s);\n";
    private static String viewName = "private %s %s;\n";
    private static XmlPullParserFactory factory;
    private static XmlPullParser parser;

    public static void main(String[] args) {

        try {
            factory = XmlPullParserFactory.newInstance();
            parser = factory.newPullParser();
            parserXMLNormal(new ByteArrayInputStream(xml.getBytes()), null);
            System.out
                    .println("-==============================================================");
            parserXML(new ByteArrayInputStream(xml.getBytes()));

            System.out
                    .println("*****************************************************************");
            parserXMLNormal(new FileInputStream(new File(xmlpath)), null);

            System.out
                    .println("-==============================================================");
            parserXML(new FileInputStream(new File(xmlpath)));

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("出错啦,蛋疼啊,就不能一次跑通吗??");
        }
    }

    /**
     * 依赖于xutis的ioc
     * 
     * @param is
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parserXML(InputStream is)
            throws XmlPullParserException, IOException {
        parser.setInput(is, "UTF-8"); // 设置输入流 并指明编码方式
        StringBuffer sb = new StringBuffer();
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = parser.next();
            if (eventType == XmlPullParser.START_TAG) {
                for (int i = 0, count = parser.getAttributeCount(); i < count; i++) {
                    if (parser.getAttributeName(i).equals("android:id")) {
                        String id = parser.getAttributeValue(i).replace(
                                "@+id/", "");
                        sb.append(String.format(viewInject, id));
                        StringBuffer idSb = new StringBuffer();
                        // 将所有_开头的首字母大写
                        if (id.contains("_")) {
                            String[] args = id.split("_");
                            for (String s : args) {
                                idSb.append(toUpperCaseFirstOne(s));
                            }
                        } else {
                            idSb.append(toUpperCaseFirstOne(id));
                        }
                        idSb.insert(0, "m");
                        sb.append(String.format(viewName, parser.getName(),
                                idSb.toString()));
                    }
                }
            }
            if (eventType == XmlPullParser.END_DOCUMENT) {
                System.out.println(sb.toString());
            }
        }

    }

    /**
     * 普通方式生成findViewById
     * 
     * @param is
     * @param valueName
     * @throws XmlPullParserException
     * @throws IOException
     */
    private static void parserXMLNormal(InputStream is, String valueName)
            throws XmlPullParserException, IOException {

        parser.setInput(is, "UTF-8"); // 设置输入流 并指明编码方式
        if (valueName == null) {
            valueName = "";
        }
        if (!valueName.contains(".") && valueName.length() > 0) {
            valueName.replace(valueName, valueName + ".");
        }
        ArrayList ids = new ArrayList();
        ArrayList views = new ArrayList();
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = parser.next();
            if (eventType == XmlPullParser.START_TAG) {
                for (int i = 0, count = parser.getAttributeCount(); i < count; i++) {
                    if (parser.getAttributeName(i).equals("android:id")) {
                        String id = parser.getAttributeValue(i).replace(
                                "@+id/", "");
                        StringBuffer idSb = new StringBuffer();
                        // 将所有_开头的首字母大写
                        if (id.contains("_")) {
                            String[] args = id.split("_");
                            for (String s : args) {
                                idSb.append(toUpperCaseFirstOne(s));
                            }
                        } else {
                            idSb.append(toUpperCaseFirstOne(id));
                        }
                        idSb.insert(0, "m");
                        views.add(String.format(viewName, parser.getName(),
                                idSb.toString()));
                        ids.add(String.format(findViewById, idSb.toString(),
                                parser.getName(), valueName, id));
                    }
                }
            }
            if (eventType == XmlPullParser.END_DOCUMENT) {
                for (String s : views) {
                    System.out.print(s);
                }
                for (String s : ids) {
                    System.out.print(s);
                }

            }
        }
    }

    // 首字母转大写
    public static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder())
                    .append(Character.toUpperCase(s.charAt(0)))
                    .append(s.substring(1)).toString();
    }
}

控制台输出模版:

private LinearLayout mEmpty;
private ProgressBar mLoadingPb;
private TextView mTvLoading;
mEmpty = (LinearLayout) findViewById(R.id.empty);
mLoadingPb = (ProgressBar) findViewById(R.id.loading_pb);
mTvLoading = (TextView) findViewById(R.id.tv_loading);
-==============================================================
@ViewInject(R.id.empty)
private LinearLayout mEmpty;
@ViewInject(R.id.loading_pb)
private ProgressBar mLoadingPb;
@ViewInject(R.id.tv_loading)
private TextView mTvLoading;

*****************************************************************
private LinearLayout mEmpty;
private ProgressBar mLoadingPb;
private TextView mTvLoading;
mEmpty = (LinearLayout) findViewById(R.id.empty);
mLoadingPb = (ProgressBar) findViewById(R.id.loading_pb);
mTvLoading = (TextView) findViewById(R.id.tv_loading);
-==============================================================
@ViewInject(R.id.empty)
private LinearLayout mEmpty;
@ViewInject(R.id.loading_pb)
private ProgressBar mLoadingPb;
@ViewInject(R.id.tv_loading)
private TextView mTvLoading;

这里只是为了方便自己的开发,减少劳动量,所以代码写的不咋样,能用就好了。有兴趣的朋友可以自己改改。最后给出demo下载地址: http://www.oschina.net/code/snippet_924286_44839

你可能感兴趣的:(Android开发,android)