Android中Layout转成Java代码

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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。