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

时间: 2024-10-12 12:08:16

Android中Layout转成Java代码的相关文章

AndroidStudio中使用XML和Java代码混合控制UI界面实现QQ相册照片列表页面

场景 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建Android项目,首先打开activity_main.xml 使用XML设置页面 将其布局改为GridLayout,并设置其行数为3,列数为4,以及设置其id. android:rowCount = "3" android:columnCount = "4" android:id

六、Android学习笔记_JNI_c调用java代码

1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // C调用java空方法 public void helloFromJava() { System.out.println("hello from java"); } // C调用java中的带两个int参数的方法 public int Add(int x, int y) { int res

Android学习笔记_JNI_c调用java代码

1.编写native方法(java2c)和非native方法(c2java): package com.example.provider; public class CallbackJava { // C调用java空方法 public void helloFromJava() { System.out.println("hello from java"); } // C调用java中的带两个int参数的方法 public int Add(int x, int y) { int res

Android中ActionBar以及menu的代码设置样式

Android中ActionBar以及menu的代码样式如何设置?今天麦子学院android开发老师主要介绍Android中ActionBar以及menu的代码设置样式,,有需求的朋友可以参阅下 menu有些xml代码 http://schemas.android.com/apk/res/android"> <="" div=""> android:title="查找1" android:orderInCategory

Android中运行的错误:java.lang.UnsatisfiedLinkError: Couldn&#39;t load locSDK3: findLibrary returned null.

今天在使用百度地图的时候运行发现报错: 明明已经加入了liblocSDK3.so,但总是无法定位.提示错误java.lang.UnsatisfiedLinkError: Couldn't load locSDK3: findLibrary returned null. 网上找了很多的资料找到一个方法: 在libs下新建一个armeabi-v7a,然后将liblocSDK3.so复制一份到该文件夹" 如果这个不行,那么新建一个armeabi文件夹再放入liblocSDK3.so就可以了. Andr

Android中layout.xml文件中加载自定义的View类

<com.bn.summer.GGView3 android:layout_width="100dip" android:layout_height="114dip" android:layout_marginLeft="11dip" /> View类的实现: package com.bn.summer; import android.content.Context; import android.content.res.Resour

【Android】利用表格布局,Android中xml文件与java的交互制作登录界面

登录界面是图形编程.网页编程的一个经典而又基础的程序. 在安卓中,如图所示一个基本登录界面: 点击取消按钮就关闭这个程序,点击登录按钮则显示用户输入的用户名与密码. 一.基本布局 这个程序利用到安卓中的表格布局. 先打开res/values/strings.xml中定义几个字符串.之所以不直接把字符串直接写在activity_main.xml的组件中,是因为免得Eclipse出现警告.这个文件的代码如下: <?xml version="1.0" encoding="ut

【转】Android 学习笔记——利用JNI技术在Android中调用、调试C++代码

原文网址:http://cherishlc.iteye.com/blog/1756762 在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在Android中会生成Linux系统下的.so文件(好吧,其实我基本没用过Linux). 没写过JNI的可以看看我之前的博客(Windows下利用Visual Studio开发的过程):http://cherishlc.iteye.com/admin/blogs/1328136 以及自动生成工具swig的

android 如何使用jar替换java代码编译

1. 第一次全编译project(随机eng/user),然后保存,以取代java代码jar包,在alps/out/target/common/obj/JAVA_LIBRARIES/xxx__intermediates夹 classes.jar javalib.jar 2. 请将以下文件保存成java_library_prebuilt.mk,并放在alps/build/core/文件夹以下: 注意:有11处须要tab键开头(make语法对命令须要tab键开头,但站点不支持tab键),请保存成文件