Android中Layout转成Java代码

原创 2015年07月08日 18:39:47

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

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

<?xml version="1.0" encoding="utf-8"?>

<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 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
            + "\n"
            + "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
            + "              android:id=\"@+id/empty\"\n"
            + "              android:layout_width=\"match_parent\"\n"
            + "              android:layout_height=\"match_parent\"\n"
            + "              android:gravity=\"center\">\n"
            + "    <ProgressBar android:id=\"@+id/loading_pb\"\n"
            + "                 android:layout_width=\"wrap_content\"\n"
            + "                 android:layout_height=\"wrap_content\"\n"
            + "                 style=\"@android:style/Widget.ProgressBar.Small.Inverse\"/>\n"
            + "    <TextView android:id=\"@+id/tv_loading\"\n"
            + "              android:layout_width=\"wrap_content\"\n"
            + "              android:layout_height=\"wrap_content\"\n"
            + "              android:layout_toRightOf=\"@+id/loading_pb\"\n"
            + "              android:text=\"加载中...\"/>\n" + "</LinearLayout>";

    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<String> ids = new ArrayList<String>();
        ArrayList<String> views = new ArrayList<String>();
        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

Java纯代码布局--原.xml文件样式的设置

我在百度找了很多的东西,没有一个准确的答案,不过还好,最终让我完成了。 在项目中给你个控件设置圆角等样式,一般情况下的处理结果,是在drawable文件夹中设置一个xml文件中设置shape, 例...

Android Layout Binder(在线将XML中View find出来,生成java代码的工具)

废话不多说,这是地址:http://android.lineten.net/layout.php。 有图有真相,例如: 你的XML假如是这样:     a...

Java代码规范-Android版

  • 2015年09月28日 09:48
  • 136KB
  • 下载

中缀表达式转成后缀表达式(含java实现的具体代码)

已转到:http://www.wypblog.com/archives/161             后缀表达式又叫做逆波兰表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,所...

android反编译看java代码工具

  • 2014年08月12日 09:04
  • 6.22MB
  • 下载

java减少数据访问层代码—反射2—将ResulSet动态转成get、set

package com.fendou.wrapper; import java.lang.reflect.Field; import java.lang.reflect.InvocationT...

C#代码如果转成JAVA

  • 2008年11月19日 11:54
  • 11KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android中Layout转成Java代码
举报原因:
原因补充:

(最多只允许输入30个字)