filter 过滤函数——万能自定义选择器的终极武器
为什么需要 filter
前面介绍的选择器都是 Auto.js 预设好的匹配条件(text、id、className…),但实际场景总会遇到预设条件覆盖不到的情况:
- text 长度在 4~8 字符之间
- 两个不同属性的组合 AND / OR
- 文本是数字且 > 100
- 控件的父节点满足某个条件
filter 让你可以自己写判断函数,返回 true 的控件保留。
基本用法
// 找到所有文本长度大于 3 的 Button
className("Button").filter(function(view) {
return view.text().length > 3;
}).forEach(function(btn) {
log("按钮:" + btn.text());
});
函数参数 view 是一个 UiObject(Auto.js 对控件的封装),可以访问所有控件属性。
常见场景
筛选文本长度
// 文本是 11 位数字(手机号)
filter(function(v) {
return v.text().length == 11 && /^\d+$/.test(v.text());
});
组合 OR 条件
// 文本包含「买」或「购」或「支付」
filter(function(v) {
var t = v.text();
return t.indexOf("买") >= 0 || t.indexOf("购") >= 0 || t.indexOf("支付") >= 0;
});
按父控件类型过滤
// 父控件是 LinearLayout 的 TextView
className("TextView").filter(function(v) {
var parent = v.parent();
return parent && parent.className() == "android.widget.LinearLayout";
});
排除导航栏
// 不在顶部(y < 100)的按钮
className("Button").filter(function(v) {
return v.bounds().top > 100;
});
性能注意
filter 需要遍历所有匹配控件并执行函数,比普通选择器慢得多。建议:
- 前面先加基础选择器缩小范围,再 filter:
className("Button").filter(...) // ✅ 好
filter(...) // ❌ 会遍历所有控件
- 不要在 filter 函数里放耗时操作(sleep、网络请求等)
- 如果 filter 逻辑很复杂,考虑拆成两步
UiObject 可用属性速查
filter 函数里 view 对象可以访问:
| 方法 | 返回 |
|---|---|
| view.text() | 文本内容 |
| view.id() | 资源 ID |
| view.className() | 类名 |
| view.description() | 无障碍描述 |
| view.bounds() | {left, top, right, bottom} |
| view.visible() | 是否可见 |
| view.clickable() | 是否可点击 |
| view.enabled() | 是否启用 |
| view.parent() | 父控件 UiObject |
| view.childCount() | 子控件数量 |