前言
本教程仅为个人理解,可能不严谨,请见谅。
本教程不会有太多的图~~,别问,问就是懒得截~~
GKD的规则编写靠的就是选择器,选择器的作用就是根据信息去定位节点。
GKD所使用的选择器是类似CSS的选择器的,所以如果写过CSS的上手会更快一些。
下面正式开始。
语法
先展示下官方的介绍:
与 css 类似, 一个选择器由 属性选择器 和 关系选择器 交叉组成, 并且开头末尾必须是 属性选择器
示例
div > img的结构是属性选择器 关系选择器 属性选择器, 它表示选择一个img节点并且它父节点是div, 这与相同 css 语法语义一致另外 属性选择器 和 关系选择器 之前必须强制用空格隔开, 也就是
div>img是非法的, 必须写成div > img
一个选择器由 属性选择器 和 关系选择器 交叉组成, 并且开头末尾必须是 属性选择器
这句是什么意思呢?第二段也有例子,如果看不懂的话,用数学来举例就明白了:1+2
式子里的1和2就是所谓属性选择器,+号就是所谓关系选择器,开头和末尾必须是属性选择器的原因也就知道了,因为像 1+2+ 这样的式子是不完整的。
属性选择器
官方的文档对于属性选择器的介绍太长,就不放全文了。
@
现在介绍一下@。
@表示选择此节点, 一条规则最后属性选择器@生效, 如果没有@, 取最后一个属性选择器
什么意思呢?这里用一条规则去举例:
FrameLayout > @FrameLayout > ViewGroup现在的@在第二个FrameLayout处,就是告诉程序:你要点击的是这个FrameLayout,而不是其它的节点。
如果现在将@删去,变成
FrameLayout > FrameLayout > ViewGroup会是什么结果?程序就不会点击第二个FrameLayout,而是点击最后的ViewGroup了。
可以将其理解为与下方的规则等价
FrameLayout > FrameLayout > @ViewGroupname属性
上节规则中的FrameLayout、ViewGroup到底是什么?
现在来介绍:name属性。
不是什么重点就随便写写啦
FrameLayout、ViewGroup,包括常见的TextView、ImageView等等,都是节点的name属性,代表着该节点的类型*(个人理解)*。
由于该选择器主要用于 Android 平台, 节点的 name 都是 java 类如 android.text.TextView 这种形式
TextView等价于[name='TextView'||name$='.TextView'],其它也是一样的。
表达式
表达式有逻辑表达式和布尔表达式,表达式一般跟在name属性后面,用[]括起来。
看到这里,你就想到上节末尾的[name='TextView'||name$='.TextView'],没错,那就是一个表达式。
表达式的作用是:限制name属性的范围。如果只写FrameLayout,那一个快照内有多少的FrameLayout,程序不能明白你要点击的是哪个FrameLayout。但是加上表达式后,程序就知道你要点击哪一个FrameLayout了
布尔表达式
布尔表达式 由
属性名操作符值构成
属性名
在网页审查工具中,红圈的地方就是属性名。
在实际规则编写中,一般不允许使用从left往下的,除childCount和index以外的属性名。
操作符
操作符有:=, !=, >, <, >=, <=, ^=, *=, $=, !^=, !*=, !$=
^=:以...开始*=:包含$=:以...结束!^=:不以...开始!*=:不包含!$=:不以...结束
这里用*=举例:
TextView[text*='123']这条规则的意思就是:选择text属性名中包含123的节点。
其它是雷同的。
值
值有4种类型:null,boolean,string,int
null,一般不用boolean:使用true或者false,比较少见string:使用"、`、'之一成对包裹,内部字符转义使用\。注意:string不支持多行字符,另外处于[0, 0x1F]的控制字符必须使用转义字符表示int:匹配0-9的数字,仅支持10进制
特别地,有些操作符只能在对应的类型使用。
如a>'',学过数学的同学都知道:大于号是用来比较数字的大小的。同样的,>这个操作符只能用于int类型的值,但是例子却用来比较string类型的值,所以它永远是不成立的。放到规则编写里,这就是非法选择器。
下面是操作符在值的类型中的可用性的表格(-表示不可用):

逻辑表达式
逻辑表达式有操作符:||和&&
||:表示或,即||的两边只需满足其一。||的两边常为布尔表达式&&:表示并且,即&&的两边需要全部满足。&&的两边常为布尔表达式
特别地,&&的优先级更高,即[a>1||b>1&&c>1||d>1]等价于[a>1||(b>1&&c>1)||d>1]


