写一个自定义控件attrs自动生成代码工具

前言:

自定义属性想必大家都知道,这个东西蛮好的,很实用,但是由属性写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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小樱的经验随笔

Codefoces 723B Text Document Analysis

B. Text Document Analysis time limit per test:1 second memory limit per test:256...

35610
来自专栏余林丰

Java中net.sf.json包关于JSON与对象互转的坑

  在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递。数据的格式通常有2种:1、xml;2、JSON。通...

3225
来自专栏Python小白进阶之旅

Python面试必备,看完轻轻松松拿到10k

平时我们几乎不可能用到的东西,像那些类里面的魔法方法,你还记得几个,这些可都是面试必备啊~

4188
来自专栏数据结构与算法

610. 数对的个数

★★   输入文件:dec.in   输出文件:dec.out 简单对比 时间限制:1 s   内存限制:128 MB Description 出题是一件...

2907
来自专栏python全栈布道师

2017年9月5日

2725
来自专栏北京马哥教育

Python高级编程技巧

正文: 本文展示一些高级的Python设计结构和它们的使用方法。在日常工作中,你可以根据需要选择合适的数据结构,例如对快速查找性的要求、对数据一致 性的要求或...

4224
来自专栏cmazxiaoma的架构师之路

你应该会的一道多线程笔试题

2543
来自专栏数据结构与算法

BZOJ1901: Zju2112 Dynamic Rankings(整体二分 树状数组)

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1

842
来自专栏Python攻城狮

MySQL中char、varchar和text的区别

它们的存储方式和数据的检索方式都不一样。 数据的检索效率是:char > varchar > text 空间占用方面,就要具体情况具体分析了。

814
来自专栏菩提树下的杨过

Flash/Flex学习笔记(8):ActionScript3.0中的面对对象

首先要习惯AS3.0的几个BT约定: 1.一个.as文件中,只能定义一个类 2.类名称必须与.as的文件名相同 3.类定义中必须要有package包声明 4.一...

1749

扫码关注云+社区