写一个自定义控件attrs自动生成代码工具
2018-11-08 本文已影响48人
e4e52c116681
前言:
自定义属性想必大家都知道,这个东西蛮好的,很实用,但是由属性写private XXX xxx;
好麻烦的说,几个也就算了,如果几十个还不写崩溃,
秉承着能用代码解决的问题,绝对不动手。能够靠智商解决的问题,绝对不靠体力
的大无畏精神:
自定义属性命名时只要规范一些,完全可以用字符串操作自动生成啊!开动
原文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--自定义进度条-->
<declare-styleable name="TolyProgressBar">
<!--进度条相关-->
<attr name="z_pb_bg_color" format="color"/>
<attr name="z_pb_on_color" format="color"/>
<attr name="z_pb_on_height" format="dimension"/>
<attr name="z_pb_bg_height" format="dimension"/>
<!--文本相关-->
<attr name="z_pb_txt_color" format="color"/>
<attr name="z_pb_txt_size" format="dimension"/>
<attr name="z_pb_txt_offset" format="dimension"/>
</declare-styleable>
</resources>
生成目标:贴上去就能用了(之后自己附上初始值)
目前只适用几种常见类型,以后有需求再完善:是不是觉得会省去很多自己写的代码
private int mPbBgColor= ;
private int mPbOnColor= ;
private int mPbOnHeight= ;
private int mPbBgHeight= ;
private int mPbTxtColor= ;
private int mPbTxtSize= ;
private int mPbTxtOffset= ;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TolyProgressBar);
mPbOnHeight = (int) a.getDimension(R.styleable.TolyProgressBar_z_pb_on_height, mPbOnHeight);
mPbTxtOffset = (int) a.getDimension(R.styleable.TolyProgressBar_z_pb_txt_offset, mPbTxtOffset);
mPbOnColor = a.getColor(R.styleable.TolyProgressBar_z_pb_on_color, mPbOnColor);
mPbTxtSize = (int) a.getDimension(R.styleable.TolyProgressBar_z_pb_txt_size, mPbTxtSize);
mPbTxtColor = a.getColor(R.styleable.TolyProgressBar_z_pb_txt_color, mPbTxtColor);
mPbBgHeight = (int) a.getDimension(R.styleable.TolyProgressBar_z_pb_bg_height, mPbBgHeight);
mPbBgColor = a.getColor(R.styleable.TolyProgressBar_z_pb_bg_color, mPbBgColor);
a.recycle();
代码实现:
1.首先你要有自己的前缀,毕竟是自己的自定义控件,统一一下也好,xml布局里也能自动提示,
2.而且还很有格调,吾的前缀是z_
,下划线分割字母用该是通识,不多说了。
注意:本工具只是针对基础的attr,以后遇到复杂的再修改升级,别挑刺:这个不行,那个不行,不行改改,反正字符串的拼接,多几个分支判断,就OK了。
/**
* 作者:张风捷特烈
* 时间:2018/10/31 0031:8:47
* 邮箱:1981462002@qq.com
* 说明:
* <p>
* <?xml version="1.0" encoding="utf-8"?>
* <resources>
* <!--自定义进度条-->
* <declare-styleable name="TolyProgressBar">
* <!--进度条相关-->
* <attr name="z_pb_bg_color" format="color"/>
* <attr name="z_pb_on_color" format="color"/>
*
* <attr name="z_pb_on_height" format="dimension"/>
* <attr name="z_pb_bg_height" format="dimension"/>
* <p>
* <!--文本相关-->
* <attr name="z_pb_txt_color" format="color"/>
* <attr name="z_pb_txt_size" format="dimension"/>
* <attr name="z_pb_txt_offset" format="dimension"/>
* </declare-styleable>
* </resources>
*/
public class AttrsFormat {
@Test
public void main() {
File file = new File("C:\\Users\\Administrator\\Desktop\\attrs.xml");
initAttr("z_", file);
}
public static void initAttr(String preFix, File file) {
HashMap<String, String> format = format(preFix, file);
String className = format.get("className");
String result = format.get("result");
StringBuilder sb = new StringBuilder();
sb.append("TypedArray a = context.obtainStyledAttributes(attrs, R.styleable." + className + ");\r\n");
format.forEach((s, s2) -> {
String styleableName = className + "_" + preFix + s;
if (s.contains("_")) {
String[] partStrArray = s.split("_");
s = "";
for (String part : partStrArray) {
String partStr = upAChar(part);
s += partStr;
}
}
if (s2.equals("dimension")) {
// mPbBgHeight = (int) a.getDimension(R.styleable.TolyProgressBar_z_pb_bg_height, mPbBgHeight);
sb.append("m" + s + " = (int) a.getDimension(R.styleable." + styleableName + ", m" + s + ");\r\n");
}
if (s2.equals("color")) {
// mPbTxtColor = a.getColor(R.styleable.TolyProgressBar_z_pb_txt_color, mPbTxtColor);
sb.append("m" + s + " = a.getColor(R.styleable." + styleableName + ", m" + s + ");\r\n");
}
if (s2.equals("boolean")) {
// mPbTxtColor = a.getColor(R.styleable.TolyProgressBar_z_pb_txt_color, mPbTxtColor);
sb.append("m" + s + " = a.getBoolean(R.styleable." + styleableName + ", m" + s + ");\r\n");
}
if (s2.equals("string")) {
// mPbTxtColor = a.getColor(R.styleable.TolyProgressBar_z_pb_txt_color, mPbTxtColor);
sb.append("m" + s + " = a.getString(R.styleable." + styleableName + ");\r\n");
}
});
sb.append("a.recycle();\r\n");
System.out.println(sb.toString());
System.out.println(result);
}
/**
* 读取文件+解析
*
* @param preFix 前缀
* @param file 文件路径
*/
public static HashMap<String, String> format(String preFix, File file) {
HashMap<String, String> container = new HashMap<>();
if (!file.exists() && file.isDirectory()) {
return null;
}
FileReader fr = null;
try {
fr = new FileReader(file);
//字符数组循环读取
char[] buf = new char[1024];
int len = 0;
StringBuilder sb = new StringBuilder();
while ((len = fr.read(buf)) != -1) {
sb.append(new String(buf, 0, len));
}
String className = sb.toString().split("<declare-styleable name=\"")[1];
className = className.substring(0, className.indexOf("\">"));
container.put("className", className);
String[] split = sb.toString().split("<");
String part1 = "private";
String type = "";//类型
String name = "";
String result = "";
StringBuilder sb2 = new StringBuilder();
for (String s : split) {
if (s.contains(preFix)) {
result = s.split(preFix)[1];
name = result.substring(0, result.indexOf("\""));
type = result.split("format=\"")[1];
type = type.substring(0, type.indexOf("\""));
container.put(name, type);
if (type.contains("color") || type.contains("dimension") || type.contains("integer")) {
type = "int";
}
if (result.contains("fraction")) {
type = "float";
}
if (result.contains("string")) {
type = "String";
}
if (result.contains("boolean")) {
type = "boolean";
}
if (name.contains("_")) {
String[] partStrArray = name.split("_");
name = "";
for (String part : partStrArray) {
String partStr = upAChar(part);
name += partStr;
}
sb2.append(part1 + " " + type + " m" + name + "= ;\r\n");
}
container.put("result", sb2.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return container;
}
/**
* 将字符串仅首字母大写
*
* @param str 待处理字符串
* @return 将字符串仅首字母大写
*/
public static String upAChar(String str) {
String a = str.substring(0, 1);
String tail = str.substring(1);
return a.toUpperCase() + tail;
}
}
自定义属性.png 自定义属性初始化.png控制台里拷贝一下就行了