autojs给view设置id

485 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情 >>

牙叔教程 简单易懂

一般写ui的时候id是这样设置的

"ui";
ui.layout(
    <vertical>
        <button id="btn" text="牙叔教程" />
    </vertical>
);

直接id="btn"

那么如果我们动态添加view呢

var child = new android.widget.Button(context);
child.setTextSize(20);
child.setTextColor(colors.parseColor("#ff00f0"));
child.setText("左护法");
child.setGravity(0);
ui.root.addView(child);

\

如果我要给这个新增的按钮设置一个id叫 左护法, 该怎么做呢?

首先, android的id肯定都是数字, 他这个autojs之所以能用中文, 或者别的字符, 是因为做了映射,

把字符和数字做映射, 然后存到一个地方, 在解读id的时候, 再把字符转换成对应的id

我们来看看autojs里面存储id的类是怎么写的

package com.stardust.autojs.core.ui.inflater.util;

import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Stardust on 2017/11/3.
 */

public class Ids {

    private static AtomicInteger maxId = new AtomicInteger(20161209);
    private static HashMap<String, Integer> ids = new HashMap<>();

    public static String parseIdName(String idName) {
        if (idName.startsWith("@+id/")) {
            return idName.substring(5);
        } else if (idName.startsWith("@id/")) {
            return idName.substring(4);
        }
        return idName;
    }

    public static int parse(String name) {
        name = parseIdName(name);
        Integer id = ids.get(name);
        if (id == null) {
            id = maxId.incrementAndGet();
            ids.put(name, id);
        }
        return id;
    }
}

\

从代码中可以看到, 所有的id都是放在ids这个 HashMap 中的, 键值对是 String, Integer, 也就是说我们在脚本UI中设置的id是作为字符串来保存, auotjs解析的时候, 再从 HashMap 中去提取对应的 Integer

上面那个类是auotjs免费版的代码, 由于autojs已经收费不开源, 所以新版的 Ids 这个类就看不到了, 不过我们可以用autojs9.2.10打包一个app, 然后用mt管理器, 在相同的包名和类名下面看到该类,

\

我们来打印一下ids中的数据, ids是Ids这个类的静态私有属性, 需要反射, 获取ids数据的步骤

第一步: 获取Ids这个类

var cls_Ids = new com.stardust.autojs.core.ui.inflater.util.Ids().getClass();

第二步: 获取指定属性

ids = cls_Ids.getDeclaredField("ids");

第三步: 关闭这个属性的访问安全检查

ids.setAccessible(true);

第四步: 获取该属性的值

let idsValue = ids.get(cls_Ids.newInstance());
log(idsValue); // {root=1, btn=2} 

\

ids这个实例我们获取到了, 接下来就可以操作他了,

我们把左护法那个按钮的id叫做左护法, 我们添加到ids里面

第一步: 生成一个view的id存起来

let viewIds = {};
viewIds.左护法 = new java.lang.Integer(View.generateViewId());

第二步: 把这个id设置给那个左护法的按钮

child.setId(viewIds.左护法);

第三步骤: 操作idsValue, 添加键值对

idsValue.put("左护法", viewIds.左护法);

第四步: 左护法进化成东方不败

ui.左护法.setText("东方不败")

第五步: 打印看看idsValue的值

log(idsValue);
// {root=1, 左护法=86, btn=2} 

总结

这个设置view的id的教程, 难点是反射, 辅助软件是MT管理器, 还应当了解hashmap的用法;

教程写出来了, 照着做就能改, 但是这个教程做出来之前是需要翻阅一些网上的教程, 并且需要看一看autojs的源码, 我指的是哪个已经不更新的开源的autojs仓库

写反射的帖子网上有很多, 我觉得这个帖子是比较好的

Java 反射详解

www.cnblogs.com/ysocean/p/6…

环境

雷电模拟器:9.0.17
Android版本: 9
Autojs版本: 9.2.10

名人名言

思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程

声明

部分内容来自网络 本教程仅用于学习, 禁止用于其他用途

微信公众号 牙叔教程