gkd 选择器入门:为什么需要高级选择器语法
选择器是 GKD 规则的「查询语言」:官方给它的定义是一个类似 CSS 选择器的选择器,能联系节点上下文信息,更容易也更精确找到目标节点。写自定义规则之前,这一课绕不开。
为什么不能只靠文字或 id 找节点
理想情况下,目标节点自带唯一标识,比如知乎开屏广告的「跳过」按钮有 btn_skip 这个 id,一条 [id="...btn_skip"] 就能定位。但真实世界里大量界面没那么友好:
- 节点缺失有效属性:很多按钮没有 id,文字也可能是空字符串或图片,靠 text/id 都找不到它;
- 节点的额外属性没被利用:控件还有尺寸、可见性、可点击性、子节点数量、在父节点中的位置等一大堆属性——节点的完整属性可以在快照审查工具的属性面板里逐个查看;
- 节点本身没特征,但邻居有:比如一个无特征的关闭图标,旁边常有「广告」文字,或者它挂在某个特定布局下面。
选择器就是为了同时解决这三个问题设计的:用任意属性组合过滤节点,用节点间的关系约束位置。
一个真实例子
官方文档里的示例选择器:
@[vid="menu"] < [vid="menu_container"] - [vid="dot_text_layout"] > [text^="广告"]
读法从右往左:先找到一个文字以「广告」开头的节点(text^= 表示以某文字开头),它的直接子节点(>)里有 dot_text_layout,这个节点的后置兄弟节点(-)是 menu_container,menu_container 的直接子节点(<)是 menu——@ 号声明最终要点击的是 menu 这个节点。
一条表达式,同时用上了文字、id、四种层级关系。这就是「联系节点上下文」的含义:目标说不清自己,就让邻居作证。
基本构成:属性选择器 + 关系选择器
与 CSS 一致,GKD 选择器由两类元素交叉组成:
- 属性选择器:方括号或类名形式,如
TextView、[text*="跳过"],负责「选谁」; - 关系选择器:
><+-<<等符号,负责「在哪」。
一条规则必须是「属性 关系 属性 关系 … 属性」的交替结构,且属性选择器和关系选择器之间必须用空格隔开——div>img 是非法的,必须写 div > img。