findviewbyid和注解方式的自动生成工具
android开发中有很多是无意义的体力活,其中一项不能省去的就是findviewbyid,所以呢也有许多自动生成的代码工具,但是总之给人的感觉就是不太符合自己的编码风格就自己写了个拿出来纪录一下。
1.首先感谢一下 http://android.lineten.net/layout.php 网站的作者,这个会自动生成findviewbyid的代码 如
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_user"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
这个布局 将这个放在 红色框的 Layout XML 中,点击 Gennerate,就会生成结果 。
上面的Model是选择是注解还是 java标准代码,java settings-scope 是选择变量修饰符,File prefix 生成变量的前缀。
仔细看生成的代码就发现,他不会把“_”去掉,和我们标准的风格不一致,只能自己在重修修改了。
项目地址:https://github.com/Xiaodisappear/xmlparse. 直接导入到idea 打成war包放在tomact webapp 目录下面就可以访问。
我只改了form表单的提交方式,和接受到请求的解析方式。
<div class="control-group">
<label for="prefix" class="control-label">Field Prefix</label>
<div class="controls controls-row">
<div class="input-append span5">
<input id="prefix" name="prefix" type="text" value="m">
<input type="button" class="btn btn-success" οnclick="dealXMLDataWithJava()"
value="Generate"
/>
</div>
</div>
<!-- controls-row -->
</div>
<!-- control-group -->
</div>
<!-- java settings -->
<div id="aaSettings" class="hidden">
<div class="control-group">
<label class="control-label"></label>
<input type="button" class="btn btn-success" οnclick="dealXMLDataWithJava()"
value="Generate"
/>
</div>
<!-- controls-row -->
</div>
如上,将原来文件中的表单提交方式拦截 用js做校验,之后用ajax 提交服务器,进行数据处理,返回之后在写入到 result中.
js代码
//将form中的值转换为键值对。
function getFormJson(frm) {
var o = {};
var a = $(frm).serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
}
function dealXMLDataWithJava() {
//获取需要解析的xml内容.
var xml = document.getElementById("xml").value;
if (xml != null && xml.length > 0) {
//获取表单数据.
var form = document.getElementById("fomXml");
//将表单数据转换成简直对的形式.
var data = getFormJson(form);
//用ajax 方式提交数据.
$.ajax({
type: "POST",
url: "${pageContext.request.contextPath}/dealXml",
data: data,
success: function (msg) {
//成功之后将数据写入results节点中
document.getElementById("results").innerText = msg;
}, error: function () {
alert("数据格式有误");
}
});
}
}
然后看接受到数据请求之后的处理。
@Controller
public class XmlParseController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
return "/layout_parse";
}
@RequestMapping(value = "/dealXml", method = RequestMethod.POST)
@ResponseBody
public String parseXml(@ModelAttribute("XmlLayoutParse") XmlLayoutParse xmlParseEntity) {
if (xmlParseEntity != null) {
xmlParseEntity.dealXmlLayout();
}
return xmlParseEntity.getResults();
}
}
这些用了spring, index 方法上面的注解说明是默认请求,请求方式为GET.也就是打开这个项目,默认访问 layou_parse 页面其中前缀和后缀看 mvc-dispatcher-servlet.xml文件下的配置,不懂的可以看 idea 构建spring 项目, 上面点击按钮,发出的请求 dealXml 会转入到 parseXml方法中 ,后面方法注解的意思是用 XmlLayoutParse 这个model去接受数据,记得mode的变量名要和jsp页面中的name一致,@ResponseBody 意思是说这个方法处理完成之后,将数据返回到Respons中去,那边会接收数据,也就是success 中msg的数据。
/**
* Work with XML data.
*/
public void dealXmlLayout() {
try {
if (!TextUtils.isEmpty(xml)) {
if (xmlMaps == null) {
xmlMaps = new HashMap<>();
}
//用dom4j解析
SAXReader reader = new SAXReader();
Document doc = reader.read(new ByteArrayInputStream(xml.getBytes("UTF-8")));
Element el = doc.getRootElement();
listNodes(el);
assembleData();
}
} catch (Exception e) {
e.printStackTrace();
}
}
这个方法是处理xml数据的,xmlMaps将 遍历的xml节点存一下,这里用到了 dom4j解析xml,需要导入jar包。
/**
* Loop reads all need id node.
*/
public void listNodes(Element node) {
List<Attribute> list = node.attributes();
for (Attribute attribute : list) {
if (attribute.getName().trim().equals(xmlIdName) && attribute.getValue().trim().contains(xmlIdAdd)) {
xmlMaps.put(attribute.getValue(), node.getName());
}
}
Iterator<Element> iterator = node.elementIterator();
while (iterator.hasNext()) {
Element e = iterator.next();
listNodes(e);
}
}
遍历xml带有+id/节点的数据,存储。
/**
* The data is organized into a Java form, or the form of annotation.
*/
public void assembleData() {
if (!xmlMaps.isEmpty()) {
String endLine = System.getProperty("line.separator", "\n");
boolean isJava = isJavaOrAa();
StringBuffer variableDataSb = new StringBuffer();
String templateVariable;
String templateFind;
if (isJava) {
templateVariable = getVariableTemplateForJava();
templateFind = getFindTemplate();
StringBuffer findDataSb = new StringBuffer();
variableDataSb.append(" // Content View Elements").append(endLine).append(endLine);
findDataSb.append(" private void bindViews() {").append(endLine).append(endLine);
for (Map.Entry<String, String> entry : xmlMaps.entrySet()) {
String key = entry.getKey().replace("@+id/", "");
String variableKey = getVariableByKey(key);
String value = entry.getValue();
variableDataSb.append(String.format(templateVariable, variableKey)).append(endLine);
findDataSb.append(String.format(templateFind, variableKey, value, key)).append(endLine);
}
variableDataSb.append(endLine).append(" // End Of Content View Elements").append(endLine).append(endLine);
findDataSb.append(endLine).append(" }");
results = variableDataSb.toString() + findDataSb.toString();
} else {
templateVariable = getVariableTemplateForAA();
templateFind = getAAFindTemplate();
String aniTemplate = new StringBuffer().append(templateFind).append(endLine).append(templateVariable).toString();
variableDataSb.append(" // Content View Elements").append(endLine).append(endLine);
for (Map.Entry<String, String> entry : xmlMaps.entrySet()) {
String key = entry.getKey().replace("@+id/", "");
String variableKey = getVariableByKey(key);
String value = entry.getValue();
variableDataSb.append(String.format(aniTemplate, key, value, variableKey)).append(endLine).append(endLine);
}
variableDataSb.append(endLine).append(" // End Of Content View Elements").append(endLine).append(endLine);
results = variableDataSb.toString();
}
}
}
完结了,验证一下成果。
java常用findviewbyid 类型。
由于我不常用注解方式来找view,这个是同事常用的方式,所以就采用了这种方式,如果大家有别的方式可以去改写代码。
项目地址:https://github.com/Xiaodisappear/xmlparse