AutoJs6 中文文档 下载 App

UiSelector 选择器 API 核心 — 控件定位的基石

什么是选择器

选择器(UiSelector)是 AutoJs6 定位屏幕控件的核心机制。它根据控件的属性(id、text、desc、className 等)筛选出你想要操作的控件,类似网页开发中的 CSS 选择器。

屏幕上的控件树:
┌──────────────────────────────┐
│  [TextView] "确定" id: btn_ok │ ← text("确定").findOne() 选中它
│  [Button]   "取消"            │ ← text("取消").findOne() 选中它
│  [EditText] "请输入" id: input│ ← id("input").findOne() 选中它
└──────────────────────────────┘

基本匹配属性

id — 最精确的定位方式

android:id 是 Android 控件的唯一标识,首选用 id 定位。

// 精确匹配
let btnOk = id("btn_ok").findOne();

// 包含匹配
let inputAny = idContains("input").findOne();

// 正则匹配(v6.7 新增)
let dynamicBtn = idMatches(/btn_\d+/).findOne();

text — 控件显示的文字

// 精确匹配
text("登录").click();

// 包含匹配
textContains("登录").click();

// 正则匹配(v6.7 支持标志位)
textMatches(/登\s*录/i).click();

// 以...开头/结尾
textStartsWith("确").click();
textEndsWith("定").click();

desc — 内容描述(无障碍描述)

部分应用不给控件设置 id 和 text,但会设置 content-description。

// 和 text 用法一样
desc("返回").click();
descContains("设置").click();
descMatches(/\d+%/).click();

className — 控件类型

// 按控件类型筛选
className("Button").findOne();
className("EditText").findOne();

// 常见 Android 控件类型
// TextView, EditText, Button, ImageView, ImageButton, CheckBox,
// Switch, RadioButton, ToggleButton, SeekBar, ProgressBar,
// ScrollView, RecyclerView, LinearLayout, FrameLayout, ConstraintLayout 等

其他匹配属性

方法说明示例
clickable(b)是否可点击clickable(true).findOne()
focusable(b)是否可聚焦focusable(true)
visibleToUser(b)是否对用户可见visibleToUser(true)
enabled(b)是否启用enabled(true)
editable(b)是否可编辑editable(true)
selected(b)是否被选中selected(true)
checked(b)是否被勾选checked(true)
scrollable(b)是否可滚动scrollable(true)
index(i)在父控件中的索引index(0)
depth(d)在控件树中的深度depth(5)

bounds — 坐标范围

// bounds 是 Rect 对象,四个值:left, top, right, bottom
// 返回控件的屏幕坐标范围

// boundsInside — 选择完全在指定区域内的控件
let controls = boundsInside(0, 1000, 1080, 1500).find();

// bounds — 精确坐标匹配
let target = bounds(0, 0, 1080, 100).findOne();

// boundsContains — 包含指定点
let point = boundsContains(500, 800).findOne();

组合多个条件

通过链式调用组合多个匹配条件,条件之间是 AND(与) 的关系:

// 找一个 id 是 btn_ 开头、文字包含"确定"、可点击的 Button
let button = idContains("btn_")
    .textContains("确定")
    .clickable(true)
    .className("Button")
    .findOne();

if (button) {
    button.click();
}

同一属性多次调用 = AND

// 这个条件要求 className 既是 Button 又是 TextView
// 实际没有控件同时满足,返回 null
className("Button").className("TextView").findOne(); // null

查找方法

findOne — 找第一个匹配

// 无超时(默认 10 秒)
let control = id("btn_ok").findOne();

// 指定超时(毫秒)
let control = id("btn_ok").findOne(5000); // 最多等 5 秒

// 找不到返回 null,不是抛异常!
let control = text("不存在的文字").findOne(1000);
console.log(control); // null
if (control) {
    control.click(); // 必须先判空再操作
}

find — 找所有匹配

// 返回 UiObject 数组(可能为空数组)
let buttons = className("Button").find();
console.log("找到 " + buttons.length + " 个 Button");

// 遍历所有按钮
buttons.forEach(btn => {
    console.log("按钮文字: " + btn.text());
});

findOnce — 立即查找

// 和 findOne 一样,但不会等待超时,立即返回
let control = id("btn_ok").findOnce();
if (control) {
    control.click();
} else {
    console.log("没找到,可能还没加载好");
}

exists — 仅判断是否存在

// 返回 true / false,不返回控件对象
if (text("确定").exists()) {
    text("确定").findOne().click();
}

// exists 也接受超时参数
if (id("loading").exists(3000)) {
    // 3 秒内 loading 都没消失,可能加载异常
}

waitFor — 等待控件出现

// 等待匹配的控件出现,默认 10 秒
text("确定").waitFor();

// 指定超时
id("login_btn").waitFor(5000);

// 等控件消失
id("loading").waitUntilGone(3000);

选择器优先级建议

1. id()           → 最优先,精确且稳定
2. text() / desc() → 次优先,人类可读
3. className() + bounds() → 补充定位
4. clickable() / visibleToUser() → 过滤干扰

避免:仅靠 className() 定位,同类控件太多容易选错。