Skip to content

Instantly share code, notes, and snippets.

@fab1an
Created April 12, 2014 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fab1an/10533872 to your computer and use it in GitHub Desktop.
Save fab1an/10533872 to your computer and use it in GitHub Desktop.
Builder for Android/Eclipse that generates references to Views
<?xml version="1.0"?>
<project name="createRMapping" default="main">
<property name="package" value="org.somecompany.somepackage" />
<target name="main">
<script language="javascript">
<classpath>
<fileset dir="libs" includes="guava*.jar" />
</classpath>
<![CDATA[
importClass(java.io.File);
importClass(com.google.common.io.Files);
importClass(com.google.common.base.Charsets);
// FUNCTIONS //
function echo(msg) {
e = project.createTask("echo");
e.setMessage(msg);
e.perform();
}
function xmlChildWalker(xml) {
var i = 0;
var child = xml.*[0];
while (child != undefined) {
yield child;
child = xml.*[++i];
}
yield false;
}
// VARIABLES //
var projectDir = project.getBaseDir().getPath();
var javaPackage = project.getProperty("package");
// Get xml files
var fs = project.createDataType("fileset");
fs.setDir(new File(projectDir + "/res/layout/"));
fs.setIncludes("**/*.xml");
var srcFiles = fs.getDirectoryScanner(project).getIncludedFiles();
// iterate over that array
for (i = 0; i < srcFiles.length; i++) {
var mapping = {};
// get the values via Java API
var filename = srcFiles[i];
var file = new File(fs.getDir(project), filename);
echo("processing: " + file);
// read into string and remove <xml> line
var xmlString = Files.toString(file, Charsets.UTF_8);
xmlString = xmlString.split("\n").splice(1).join("\n");
// walk xml
var xcw = xmlChildWalker(new XML(xmlString));
var child;
while ((child = xcw.next()) !== false) {
for (var j = 0; j < child.attributes().length(); j++) {
var attr = child.attributes()[j];
var attrName = attr.localName();
if (attrName == "id") {
var id = attr.toString();
id = id.substring(5);
var clazz = child.name();
mapping[id] = clazz;
}
}
}
var layoutBaseName = filename.substring(0, filename.length() - 4);
var javaClassName = "ViewRef_" + layoutBaseName;
/* OUTPUT */
var str = "";
/* package + imports */
str += "package " + javaPackage + ";\n \n";
str += "import android.view.*;\n";
str += "import android.widget.*;\n";
str += "import java.lang.String;\n";
/* class start */
str += "\n \n";
str += "@SuppressWarnings(\"unused\")\n";
str += "public final class " + javaClassName + " {\n \n";
/* members */
for (var id in mapping) {
var type = mapping[id];
/* strip layout_ if specified */
var memberName = id;
if (id.indexOf(layoutBaseName + "_") == 0) {
memberName = id.substring(layoutBaseName.length() + 1);
}
str += "\tpublic final " + type + " " + memberName + ";\n";
}
/* constructor */
str += "\n \n";
str += "\tprivate " + javaClassName + "(View root) {\n";
for (var id in mapping) {
var type = mapping[id];
/* strip layout_ if specified */
var memberName = id;
if (id.indexOf(layoutBaseName + "_") == 0) {
memberName = id.substring(layoutBaseName.length() + 1);
}
str += "\t\tthis." + memberName + " = (" + type + ") root.findViewById(R.id." + id + ");\n";
}
str += "\t}\n \n";
/* static creator */
str += "\tpublic static " + javaClassName + " create(View root) {\n";
str += "\t\treturn new " + javaClassName + "(root);\n";
str += "\t}\n \n";
str += "\n}";
out = project.createTask("echo");
out.setMessage(str);
var packageDir = projectDir + "/gen/" + javaPackage.replace('.', "/");
out.setFile(new File(packageDir + "/" + javaClassName + ".java"));
out.perform();
}
]]></script>
</target>
</project>
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text1" />
<ScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="350px"
android:layout_below="@id/text2"
android:layout_marginTop="50px" />
</merge>
public final class TestView extends RelativeLayout {
//~ Constructors ---------------------------------------------------------------------------------------------------
private final ViewRef_test;
public TestView(final Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.test, this, true);
this.v = ViewRef_test.create(this);
this.v.text1.setText();
this.v.scroll.doSomething();
}
}
/* generated file */
package org.somecompany.somepackage;
import android.view.*;
import android.widget.*;
import java.lang.String;
@SuppressWarnings("unused")
public final class ViewRef_test {
public final TextView text1;
public final TextView text2;
public final ScrollView scroll;
private ViewRef_test(View root) {
this.text1 = (TextView) root.findViewById(R.id.text1);
this.text2 = (TextView) root.findViewById(R.id.text2);
this.scroll = (ScrollView) root.findViewById(R.id.scroll);
}
public static ViewRef_test create(View root) {
return new ViewRef_test(root);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment