首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >玩转字符串篇--代码自动生成,解放双手

玩转字符串篇--代码自动生成,解放双手

作者头像
张风捷特烈
发布于 2022-09-20 02:00:01
发布于 2022-09-20 02:00:01
5160
举报
零、前言:

1.RecyclerView的Adapter自动生成器(含ViewHolder) 2.自定义属性的自定义View代码生成器(含自定义属性的初始化) 3.svg图标转换为Android可用xml生成器

最近喜欢切割字符串,这三个类是近期的作品,感觉挺好用的,在此分享一下 三个工具都会贴在本文末尾,本文末尾,本文末尾


一、RecyclerView的Adapter自动生成器(含ViewHolder)

最近写了几个RecyclerView的Adapter,控件一多ViewHolder写起来感觉挺不爽的 也感觉其中也只是布局文件里的几个id和View的类型有区别,写个工具读一下xml自动生成一下呗 既然ViewHolder自动生成了,顺便吧Adapter也一起生成算了,反正初始也就那一大段

演示一下:

1.把工具类拷贝到test包里 2.写上你xml的路径和生成的.java所在的包 3.点击运行,就可以生成了。如果有问题,欢迎指出


Xml代码
代码语言:javascript
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:id="@+id/id_cl_root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    tools:context=".MainActivity">
    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginStart="20dp"
        android:id="@+id/id_iv_icon"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
    <TextView
        android:id="@+id/id_tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:maxLines="1"
        android:text="name"
        android:textColor="#000000"
        android:textSize="18sp"
        app:layout_constraintBottom_toTopOf="@id/id_iv_info"
        app:layout_constraintStart_toEndOf="@id/id_iv_icon"
        app:layout_constraintTop_toTopOf="@id/id_iv_icon"/>
    <TextView
        android:id="@+id/id_iv_info"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:ellipsize="end"
        android:maxLines="2"
        android:text="infoinfoinfoinfo"
        android:textColor="@color/qq_line"
        android:textSize="12sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@id/guide_v_95"
        app:layout_constraintStart_toEndOf="@id/id_iv_icon"
        app:layout_constraintTop_toBottomOf="@id/id_tv_name"/>
    <android.support.constraint.Guideline
        android:id="@+id/guide_v_95"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.95"
        />
</android.support.constraint.ConstraintLayout>
自动生成的Adapter

点一下,就生成这么多,一个一个敲怎么也要五分钟吧,这种枯燥的工作,还是留给计算机吧。 之后根据自己的业务需求,小修补一下就行了。


附加赠送:findViewById自动生成,控制台里,拷贝即用

虽然喜欢用butterknife,但感觉每次加依赖好麻烦,也就是想找个id,也没必要引个库,毕竟都占空间的。


二、自定义属性的自定义View代码生成器(含自定义属性的初始化)

这可谓我的得意之作,本人比较喜欢自定义控件,但自定义属相写起来费心费力,也没什么含量 基本上也就那么几个属性在变,一咬牙,写个工具类吧,然后就有了下文:

演示一下使用:

1.把工具类拷贝到test包里 2.写上你xml的路径和生成的.java所在的包,写上你的专属前缀 3.点击运行,就可以生成了。如果有问题,欢迎指出 注意点:自定义属性必须有自己的专属前缀(任意字符都可以,统一即可)


attrs.xml文件:
代码语言:javascript
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TolyProgressBar">
        <attr name="z_pb_bg_color" format="color"/>
        <attr name="z_pb_bg_height" format="dimension"/>
        <attr name="z_pb_on_color" format="color"/>
        <attr name="z_pb_on_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"/>
        <attr name="z_pb_txt_gone" format="boolean"/>
    </declare-styleable>
</resources>

3.svg图标转换为Android可用xml生成器

和上面一样,将所有svg放在一个文件夹里,即可批处理


附录
1:Xml2Adapter.java
代码语言:javascript
AI代码解释
复制
/**
 * 作者:张风捷特烈
 * 时间:2018/10/31 0031:8:47
 * 邮箱:1981462002@qq.com
 * 说明:初始化RecyclerView的Adapter
 */
public class Xml2Adapter {
    @Test
    public void main() {
        //你的布局xml所在路径
        File file = new File("I:\\Java\\Android\\APL\\VVI_MDs\\test\\src\\main\\res\\layout\\item_goods_list.xml");
        //你的Adapter的java类放在哪个包里
        File out = new File("I:\\Java\\Android\\APL\\VVI_MDs\\app\\src\\main\\java\\com\\toly1994\\vvi_mds\\pkg_08_other\\adapter");
        //你的Adapter的名字--不要加.java
        String name = "GoodsAdapter";
        initView(file, out, name);
    }

    @Test
    public void findView() {
        //你的布局xml所在路径
        File file = new File("I:\\Java\\Android\\Unit\\B\\asyn\\src\\main\\res\\layout\\item_list_pic.xml");
        findViewById(file);
    }

    private void findViewById(File in) {
        String res = readFile(in);
        HashMap<String, String> map = split(res);
        StringBuilder sb = new StringBuilder();
        map.forEach((id, view) -> {
            sb.append("public ").append(view).append(" ").append(formatId2Field(id)).append(";").append("\r\n");
        });
        sb.append("\n\n");
        map.forEach((id, view) -> {
            sb.append(formatId2Field(id))
                    .append("= itemView.findViewById(R.id.")
                    .append(id).append(");").append("\r\n");

            if ("Button".equals(view)) {
                sb.append(formatId2Field(id) + ".setOnClickListener(v -> {\n" +
                        "        });\n");
            }
        });
        System.out.println(sb.toString());
    }

    /**
     * 读取文件
     *
     * @param in   xml文件路径
     * @param out  输出的java路径
     * @param name
     */
    private static void initView(File in, File out, String name) {
        FileWriter fw = null;
        try {
            HashMap<String, String> map = split(readFile(in));
            String result = contactAdapter(in, out, name, map);

            //写出到磁盘
            File outFile = new File(out, name + ".java");
            fw = new FileWriter(outFile);
            fw.write(result);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 读取文件
     *
     * @param in
     * @return
     */
    private static String readFile(File in) {
        if (!in.exists() &amp;&amp; in.isDirectory()) {
            return "";
        }

        FileReader fr = null;
        try {
            fr = new FileReader(in);
            //字符数组循环读取
            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));
            }

            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 直接拼接出Adapter
     */
    private static String contactAdapter(File file, File out, String name, HashMap<String, String> map) {
        StringBuilder sb = new StringBuilder();
        String path = out.getAbsolutePath();
        path.split("java");

        sb.append("package " + path.split("java\\\\")[1].replaceAll("\\\\", ".") + ";\n");
        sb.append("import android.content.Context;\n" +
                "import android.support.annotation.NonNull;\n" +
                "import android.support.constraint.ConstraintLayout;\n" +
                "import android.support.v7.widget.RecyclerView;\n" +
                "import android.view.LayoutInflater;\n" +
                "import android.view.View;\n" +
                "import android.view.ViewGroup;\n" +
                "import android.widget.Button;\n" +
                "import java.util.List;\n" +
                "import android.widget.TextView;\n");
        sb.append("public class " + name + " extends RecyclerView.Adapter<" + name + ".MyViewHolder> {\n");
        sb.append("private Context mContext;\n");
        sb.append("private List<String> mData;\n");
        sb.append("public " + name + "(List<String> data) {\n" +
                "    mData = data;\n" +
                "}");

        String layoutId = file.getName().substring(0, file.getName().indexOf(".x"));
        sb.append("@NonNull\n" +
                "@Override\n" +
                "public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {\n" +
                "mContext = parent.getContext();\n" +
                "    View view = LayoutInflater.from(mContext).inflate(R.layout." + layoutId + ", parent, false);\n" +
                "    return new MyViewHolder(view);\n" +
                "}\n");

        sb.append("@Override \n" +
                "public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {\n" +
                "String str = mData.get(position);"
        );

        map.forEach((id, view) -> {

            if (view.contains("\n")) {
                view = view.split("\n")[0];
            }

            if ("Button".equals(view)) {
                sb.append("holder." + formatId2Field(id) + ".setOnClickListener(v -> {\n" +
                        "        });\n");
            }

            if ("TextView".equals(view)) {
                sb.append("holder." + formatId2Field(id) + ".setText(str);\n");
            }
            if ("ImageView".equals(view)) {
                sb.append("holder." + formatId2Field(id) + ".setImageBitmap(null);\n");
            }
        });

        sb.append("}\n" +
                "@Override\n" +
                "public int getItemCount() {\n" +
                "return mData.size();\n" +
                "}");

        sb.append(contactViewHolder(map));
        return sb.toString();
    }

    /**
     * 连接字符串:ViewHolder
     */
    private static String contactViewHolder(HashMap<String, String> map) {
        StringBuilder sb = new StringBuilder();
        sb.append("class MyViewHolder extends RecyclerView.ViewHolder {\r\n");
        map.forEach((id, view) -> {
            if (view.contains("\n")) {
                view = view.split("\n")[0];
            }

            sb.append("public ").append(view).append(" ")
                    .append(formatId2Field(id)).append(";").append("\r\n");
        });

        sb.append("public MyViewHolder(View itemView) {\n" +
                "super(itemView);");

        map.forEach((id, view) -> {
            sb.append(formatId2Field(id))
                    .append("= itemView.findViewById(R.id.")
                    .append(id).append(");").append("\r\n");
        });
        sb.append("}\n" +
                "}\n}");

        return sb.toString();
    }

    private static String formatId2Field(String id) {
        if (id.contains("_")) {
            String[] partStrArray = id.split("_");
            id = "";
            for (String part : partStrArray) {
                String partStr = upAChar(part);
                id += partStr;
            }
        }
        return "m" + id;
    }

    /**
     * 将字符串仅首字母大写
     *
     * @param str 待处理字符串
     * @return 将字符串仅首字母大写
     */
    public static String upAChar(String str) {
        String a = str.substring(0, 1);
        String tail = str.substring(1);
        return a.toUpperCase() + tail;
    }

    private static HashMap<String, String> split(String res) {
        String[] split = res.split("<");
        HashMap<String, String> viewMap = new HashMap<>();
        for (String s : split) {
            if (s.contains("android:id=\"@+id") &amp;&amp; !s.contains("Guideline")) {
                String id = s.split("@")[1];
                id = id.substring(id.indexOf("/") + 1, id.indexOf("\""));
                String view = s.split("\r\n")[0];
                String[] viewNameArr = view.split("\\.");
                if (viewNameArr.length > 0) {
                    view = viewNameArr[viewNameArr.length - 1];
                }
                viewMap.put(id, view);
            }
        }
        return viewMap;
    }
}

2.Attrs2View.java
代码语言:javascript
AI代码解释
复制
/**
 * 作者:张风捷特烈
 * 时间:2018/10/31 0031:8:47
 * 邮箱:1981462002@qq.com
 * 说明:安卓自定义属性,代码生成器
 */
public class Attrs2View {
    @Test
    public void main() {
        //你的attr.xml所在路径
        File file = new File("I:\\Java\\Android\\Unit\\B\\test\\src\\main\\res\\values\\attrs.xml");
        //你的Adapter的java类放在哪个包里
        File out = new File("I:\\Java\\Android\\Unit\\B\\asyn\\src\\main\\java\\com\\toly1994\\app");
        String preFix = "z_";
        //你的前缀
        initAttr(preFix, file, out);
    }

    public static void initAttr(String preFix, File file, File out) {
        HashMap<String, String> format = format(preFix, file);
        String className = format.get("className");
        String result = format.get("result");

        StringBuilder sb = initTop(out, className, result);
        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");

        sb.append("init();\n" +
                "    }");
        sb.append("private void init() {\n" +
                "\n" +
                "    }\n}");
        System.out.println(sb.toString());

        FileWriter fw = null;
        try {
            //写出到磁盘
            File outFile = new File(out, className + ".java");
            fw = new FileWriter(outFile);
            fw.write(sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /*
     *
     * @param out
     * @param name
     */
    private static StringBuilder initTop(File out, String name, String field) {
        StringBuilder sb = new StringBuilder();
        String path = out.getAbsolutePath();
        path.split("java");
        sb.append("package " + path.split("java\\\\")[1].replaceAll("\\\\", ".") + ";\n");
        sb.append("public class " + name + " extends View {\n");
        sb.append(field);
        sb.append("public " + name + "(Context context) {\n" +
                "    this(context, null);\n" +
                "}\n" +
                "public " + name + "(Context context, AttributeSet attrs) {\n" +
                "    this(context, attrs, 0);\n" +
                "}\n" +
                "public " + name + "(Context context, AttributeSet attrs, int defStyleAttr) {\n" +
                "    super(context, attrs, defStyleAttr);\n");

        return sb;
    }

    /**
     * 读取文件+解析
     *
     * @param preFix 前缀
     * @param file   文件路径
     */
    public static HashMap<String, String> format(String preFix, File file) {
        HashMap<String, String> container = new HashMap<>();
        if (!file.exists() &amp;&amp; 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 = "";
            String def = "";//默认值

            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";
                        def = "0";
                    }
                    if (result.contains("fraction")) {
                        type = "float";
                        def = "0.f";
                    }
                    if (result.contains("string")) {
                        type = "String";
                        def = "\"toly\"";
                    }
                    if (result.contains("boolean")) {
                        type = "boolean";
                        def = "false";

                    }
                    if (name.contains("_")) {
                        String[] partStrArray = name.split("_");
                        name = "";
                        for (String part : partStrArray) {
                            String partStr = upAChar(part);
                            name += partStr;
                        }
                        sb2.append(part1 + " " + type + " m" + name + "= " + def + ";\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;
    }
}

3.Svg2Xml.java
代码语言:javascript
AI代码解释
复制
/**
 * 作者:张风捷特烈
 * 时间:2018/10/31 0031:8:47
 * 邮箱:1981462002@qq.com
 * 说明:svg图标转换为Android可用xml生成器
 */
public class Svg2Xml {

    @Test
    public void svgDir() {
        String dirPath = "E:\\Material\\MyUI\\#svg\\factory";
        svg2xmlFromDir(dirPath);
    }

    @Test
    public void singleSvg() {
        File file = new File("C:\\Users\\Administrator\\Desktop\\dao.svg");
        svg2xml(file);
    }

    /**
     * 将一个文件夹里的所有svg转换为xml
     *
     * @param filePath
     */
    public static void svg2xmlFromDir(String filePath) {

        File file = new File(filePath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                if (f.getName().endsWith(".svg")) {
                    System.out.println(f);
                    svg2xml(f);
                }
            }
        } else {
            svg2xml(file);
        }
    }

    /**
     * 将.svg文件转换为安卓可用的.xml
     *
     * @param file 文件路径
     */
    public static void svg2xml(File file) {
        if (!file.exists() &amp;&amp; file.isDirectory()) {
            return;
        }

        FileWriter fw = null;
        FileReader fr = null;
        ArrayList<String> paths = new ArrayList<>();
        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));
            }
            //收集所有path
            collectPaths(sb.toString(), paths);

            //拼接字符串
            StringBuilder outSb = contactStr(paths);
            //写出到磁盘
            File outFile = new File(file.getParentFile(), file.getName().substring(0, file.getName().lastIndexOf(".")) + ".xml");
            fw = new FileWriter(outFile);
            fw.write(outSb.toString());

            System.out.println("转换成功:" + file.getName());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
                if (fr != null) {
                    fr.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 拼接字符串
     *
     * @param paths
     * @return
     */
    private static StringBuilder contactStr(ArrayList<String> paths) {
        StringBuilder outSb = new StringBuilder();
        outSb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
                "        android:width=\"48dp\"\n" +
                "        android:height=\"48dp\"\n" +
                "        android:viewportWidth=\"1024\"\n" +
                "        android:viewportHeight=\"1024\">\n");
        for (String path : paths) {
            outSb.append("    <path\n" +
                    "        android:fillColor=\"#FF7F47\"\nandroid:pathData=\"");
            outSb.append(path);
            outSb.append("\"/>");
        }
        outSb.append("</vector>");
        return outSb;
    }

    /**
     * 收集所有path
     *
     * @param result
     * @param paths
     */
    private static void collectPaths(String result, ArrayList<String> paths) {
        String regex = " d=\"(?<res>(.)*?)\"";
        Matcher matcher = Pattern.compile(regex).matcher(result);
        while (matcher.find()) {
            String path = matcher.group("res");
            paths.add(path);
        }
    }
}

后记:捷文规范
1.本文成长记录及勘误表

项目源码

日期

备注

V0.1--

2018-11-14

分享一下我的三个代码自动生成工具类--助你解放双手

V0.2--

2018-12-7

svg2Xml使用正则进行匹配

2.更多关于我

笔名

QQ

微信

爱好

张风捷特烈

1981462002

zdl1994328

语言

我的github

我的简书

我的掘金

个人网站

3.声明

1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
写一个自定义控件attrs自动生成代码工具
前言: 自定义属性想必大家都知道,这个东西蛮好的,很实用,但是由属性写private XXX xxx; 好麻烦的说,几个也就算了,如果几十个还不写崩溃, 秉承着能用代码解决的问题,绝对不动手。能
张风捷特烈
2018/12/10
5530
写一个自定义控件attrs自动生成代码工具
Android原生绘图进度条+简单自定义属性代码生成器
零、前言 1.感觉切拼字符串是个很有意思的事,好的拼接方式可以自动生成一些很实用的东西 2.本文自定义控件并不是很高大上的东西,目的在于计录自定义控件的书写规范与行文流程 3.建议大家自定义控件
张风捷特烈
2018/12/07
1.3K0
Android原生绘图进度条+简单自定义属性代码生成器
自己写一个svg转化为安卓xml的工具类
svg资源阿里巴巴矢量资源网站:http://www.iconfont.cn/ 感觉一般的svg到Android可用的xml差异有点规律,主要的就是path 秉承着能用代码解决的问题,绝对不动手。
张风捷特烈
2018/12/05
2.2K0
玩转字符串篇--Gradle+代码生成器=懒人必备
前言:我是爱偷懒的勤快人 我们的口号是: 能用脑子解决的绝对不靠体力,能用电脑完成的绝对不靠脑子,能懒就懒,懒出奇迹 1.1:关于代码 你眼中的代码是什么,类的逻辑关系?方法的实现?不要忽略
张风捷特烈
2020/04/30
7960
玩转字符串篇--Gradle+代码生成器=懒人必备
APK安装流程详解9——PackageParser解析APK(上)
为了让咱们更好的理解谷歌的安卓团队对PackageParser的定位,我们来看下PackageParser的注释
隔壁老李头
2018/08/30
6.5K0
APK安装流程详解9——PackageParser解析APK(上)
一个java代码生成器的简单实现
最近,一直跟着公司技术牛人在搞大数据相关的东西,主要涉及的是环境搭建,同时也了解下整个hadoop生态系统相关的东西,真是让我大开眼界,这个在之后的博文中再来与大家分享。 今天,笔者给大家介绍一个代码生成器,这个是笔者的主管写的,写的确实不错,主要是基于公司的jquery easyUI + springMVC + myBatis这套框架写的,可以根据一个数据库表生成model、mapper.xml、dao接口以及service、controller、jsp页面等相关的东西,包含增删改查等操作,节省开发时间。然后,笔者在此代码生成器上修改了几个bug,同时兼容了一下mysql。 这个代码生成器工具使用的核心是freemarker,一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。 下面,笔者开始进行核心代码的介绍。 首先,我们必须指定哪张表,然后通过jdbc获取这个表的信息以及表字段相关的信息。 这里,将所有的配置写入config.properties:
全栈程序员站长
2022/07/01
1K1
玩转字符串篇--替换的鬼斧神工
本文说明 1.1.问题 今天遇到一个问题,就是如何指定批量代换某些字符串。 场景:比如下面一段markdown,写文章时遇到很多固定的链接时,总是很长一段。 特别是表格里,感觉要崩溃啊,而且万一哪天要换个网址,一个个改还不改疯掉。 不行,得想个办法,再怎么说咱也是会敲些Hello World代码的人,逼格不能输。 Padding是一个可以产生内边距的控件 详情可见:![Padding](https://juejin.im/user/5b42c0656fb9a04fe727eb37/collect
张风捷特烈
2020/04/30
6470
玩转字符串篇--替换的鬼斧神工
通过GET方式传递数据给服务器
自动生成的ServerGET.java中有 @WebServlet(“/ServerGET”) 所以web.xml就不需要配置了
提莫队长
2019/02/21
1.5K0
[android] xml文件的序列化
生成xml文件,模拟备份短信,创建短信的业务bean,创建一个domain的包放业务bean,这个业务bean里面,定义成员属性,生成get set方法,生成有参和无参的构造方法。
唯一Chat
2019/09/10
1K0
安卓基础干货(二):安卓测试以及解析
1.测试的相关概念 根据是否知道源代码分类: 黑盒测试: a - b - c 边值测试 白盒测试: 根据源代码写测试方法 或者 测试用例; 根据测试的粒度分类: 方法测试:写完一个方法后就测试 单元测试:测试一个能够独立运行的业务逻辑单元; 集成测试:整体测试项目 联调 系统测试:对整个系统进行测试 根据测试的暴力程度: 1、冒烟测试:高频次的点击软件 2、压力测试:使用测试工具:LoadRunner、Jmeter 2.单元测试 Junit 01_Junit单元测试 does not
緣來
2018/09/18
1.1K0
手机卫士-12_下载百度手机卫士
江民炸弹:逻辑炸弹(非常恶意的病毒)。报复盗版: mbr:硬盘的引导区 逻辑炸弹就是破坏mbr,导致电脑启动不了。
全栈程序员站长
2022/11/09
1.2K0
手机卫士-12_下载百度手机卫士
Android字符串相机
很早就看到过这种场景,用字符来展示图片甚至播放视频,可以说是黑客炫(zhuang)技(b)神器。当然有了一定的技术之后,就明白其实实现挺简单。
音视频开发进阶
2019/08/09
1K0
Android与C#里自定义HashTable与Json转换
最近自己在做的一个程序,后端用的.net C#,其中有相关的一些数据加了自定久的属性,所以用到了HashTable,由于安卓端与后端通信用到的Json数据,所以这部分东西也用到HashTable。以前的程序经常会用到HashMap,只不过没做到通守HashMap转换为Json,所以这次做个Demo看看效果。
Vaccae
2019/07/25
1.1K0
算法细节系列(34):再见字符串(2)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/73162334
用户1147447
2019/05/26
3830
[android] post请求接口demo测试代码
MainActivity.java package com.tsh.test; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.content.Intent; import androi
唯一Chat
2019/09/11
2.2K0
Android 百度图像识别(详细步骤+源码)(下)
你可以看到这个Token还是挺长的。对于这个Token,是有有效期的,基本上是一个月,所以你可以不用每次使用时都重新请求这个接口去获取Token,这里可以用缓存来解决这个问题。
晨曦_LLW
2021/04/22
1.6K3
Android 百度图像识别(详细步骤+源码)(下)
C002Android学习笔记-初级控件(二)
xml中——textAppearance;代码中——setTextAppearance;
訾博ZiBo
2025/01/06
2910
C002Android学习笔记-初级控件(二)
Android应用界面开发——WebView
该实例包含两个界面,第一个界面包括输入网址和打开网址,第二个界面包含一个WebView,用于显示第一个界面输入的URL对应的界面。程序代码如下:
trampcr
2018/09/28
1.1K0
Android应用界面开发——WebView
android 十八 蓝牙及Wi-Fi
蓝牙是一种重要的短距离无线通信技术,它被广泛应用于各种设备,比如计算机、手机、汽车等,支持设备之间的近距离通信,从而是数据传输更加快捷有效。Wi-Fi是一种高速的无线通信协议,它具有传输速度高,传输距离长的特点。通过WiFi,手机、PDA、电脑等移动设备可以以无线方式连接网络。本节中我们主要来学习Android开发中如何调用系统中蓝牙以及wifi的功能。
张哥编程
2024/12/17
5260
android 十八 蓝牙及Wi-Fi
用户界面开发基础
Activity是Android中最核心的应用程序组件,也是大多数程序必须使用的用于显示界面的组件。
小小工匠
2021/08/16
2.3K0
相关推荐
写一个自定义控件attrs自动生成代码工具
更多 >
LV.0
这个人很懒,什么都没有留下~
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
首页
学习
活动
专区
圈层
工具
MCP广场
首页
学习
活动
专区
圈层
工具
MCP广场