Auto.js入门:简单脚本程序编写(基于控件的操作2:UiSelector)

UiSelector

UiSelector即选择器,用于通过各种条件选取屏幕上的控件,再对这些控件进行点击、长按等动作。这里需要先简单介绍一下控件和界面的相关知识。
一般软件的界面是由一个个控件构成的,例如图片部分是一个图片控件(ImageView),文字部分是一个文字控件(TextView);同时,通过各种布局来决定各个控件的位置,例如,线性布局(LinearLayout)里面的控件都是按水平或垂直一次叠放的,列表布局(AbsListView)则是以列表的形式显示控件。
控件有各种属性,包括文本(text), 描述(desc), 类名(className), id等等。我们通常用一个控件的属性来找到这个控件,例如,想要点击QQ聊天窗口的"发送"按钮,我们就可以通过他的文本属性为"发送"来找到这个控件并点击他,具体代码为:

var sendButton = text("发送").findOne();
sendButton.click();

在这个例子中,text(“发送”)表示一个条件(文本属性为"发送"),findOne()表示基于这个条件找到一个符合条件的控件,从而我们可以得到发送按钮sendButton,再执行sendButton.click()即可点击"发送"按钮。
用文本属性来定位按钮控件、文本控件通常十分有效。但是,如果一个控件是图片控件,比如Auto.js主界面右上角的搜索图标,他没有文本属性,这时需要其他属性来定位他。我们如何查看他有什么属性呢?首先打开悬浮窗和无障碍服务,点击蓝色的图标(布局分析), 可以看到以下界面:
之后我们点击搜索图标,可以看到他有以下属性:
我们注意到这个图标的desc(描述)属性为"搜索",那么我们就可以通过desc属性来定位这个控件,得到点击搜索图标的代码为:
desc(“搜索”).findOne().click();
可能心细的你可能注意到了,这个控件还有很多其他的属性,例如checked, className, clickable等等,为什么不用这些属性来定位搜索图标呢?答案是,其他控件也有这些值相同的属性、尝试一下你就可以发现很多其他控件的checked属性和搜索控件一样都是false,如果我们用checked(false)作为条件,将会找到很多控件,而无法确定哪一个是搜索图标。因此,要找到我们想要的那个控件,选择器的条件通常需要是可唯一确定控件的。我们通常用一个独一无二的属性来定位一个控件,例如这个例子中就没有其他控件的desc(描述)属性为"搜索"。
另外,对于这个搜索图标而言,id属性也是唯一的,我们也可以用id(“action_search”).findOne().click()来点击这个控件。如果一个控件有id属性,那么这个属性很可能是唯一的,除了以下几种情况:
QQ的控件的id属性很多都是"name",也就是在QQ界面难以通过id来定位一个控件
列表中的控件,比如QQ联系人列表,微信联系人列表等
尽管id属性很方便,但也不总是最方便的,例如对于微信和网易云音乐,每次更新他的控件id都会变化,导致了相同代码对于不同版本的微信、网易云音乐并不兼容。
除了这些属性外,主要还有以下几种属性:
className类名。类名表示一个控件的类型,例如文本控件为"android.widget.TextView", 图片控件为"android.widget.ImageView"等。
packageName包名。包名表示控件所在的应用包名,例如QQ界面的控件的包名为"com.tencent.mobileqq"。
bounds控件在屏幕上的范围。
drawingOrder控件在父控件的绘制顺序。
indexInParent控件在父控件的位置。
clickable控件是否可点击。
longClickable控件是否可长按。
checkable控件是否可勾选。
checked控件是否可已勾选。
scrollable控件是否可滑动。
selected控件是否已选择。
editable控件是否可编辑。
visibleToUser控件是否可见。
enabled控件是否已启用。
depth控件的布局深度。

有时候只靠一个属性并不能唯一确定一个控件,这时需要通过属性的组合来完成定位,例如className(“ImageView”).depth(10).findOne().click(),通过链式调用来组合条件。
通常用这些技巧便可以解决大部分问题,即使解决不了问题,也可以通过布局分析的"生成代码"功能来尝试生成一些选择器代码。接下来的问题便是对选取的控件进行操作,包括:
click()点击。点击一个控件,前提是这个控件的clickable属性为true
longClick()长按。长按一个控件,前提是这个控件的longClickable属性为true
setText()设置文本,用于编辑框控件设置文本。
scrollForward(),scrollBackward()滑动。滑动一个控件(列表等), 前提是这个控件的scrollable属性为true
exits()判断控件是否存在
waitFor()等待控件出现
这些操作包含了绝大部分控件操作。根据这些我们可以很容易写出一个"刷屏"脚本(代码仅为示例,请不要在别人的群里测试,否则容易被踢):
while(true){
className(“EditText”).findOne().setText(“刷屏…”);
text(“发送”).findOne().clicK();}
上面这段代码也可以写成:
while(true){
className(“EditText”).setText(“刷屏…”);
text(“发送”).clicK();}
如果不加findOne()而直接进行操作,则选择器会找出所有符合条件的控件并操作。
另外一个比较常用的操作的滑动。滑动操作的第一步是找到需要滑动的控件,例如要滑动QQ消息列表则在悬浮窗布局层次分析中找到AbsListView,这个控件就是消息列表控件,如下图:
长按可查看控件信息,注意到其scrollable属性为true,并找出其id为"recent_chat_list",从而下滑QQ消息列表的代码为:
id(“recent_chat_list”).className(“AbsListView”).findOne().scrollForward();
scrollForward()为向前滑,包括下滑和右滑。
选择器的入门教程暂且要这里,更多信息可以查看下面的文档和选择器进阶。

selector()

返回
创建一个新的选择器。但一般情况不需要使用该函数,因为可以直接用相应条件的语句创建选择器。
由于历史遗留原因,本不应该这样设计(不应该让id(),text()等作为全局函数,而是应该用By.id(),By.text()),但为了后向兼容性只能保留这个设计。
这样的API设计会污染全局变量,后续可能会支持"去掉这些全局函数而使用By.*"的选项。

UiSelector.text(str)

str控件文本
返回返回选择器自身以便链式调用
为当前选择器附加控件"text等于字符串str"的筛选条件。
控件的text(文本)属性是文本控件上的显示的文字,例如微信左上角的"微信"文本。

UiSelector.textContains(str)

str要包含的字符串
为当前选择器附加控件"text需要包含字符串str"的筛选条件。
这是一个比较有用的条件,例如QQ动态页和微博发现页上方的"大家都在搜…"的控件可以用textContains(“大家都在搜”).findOne()来获取。

UiSelector.textStartsWith(prefix)

prefix前缀
为当前选择器附加控件"text需要以prefix开头"的筛选条件。
这也是一个比较有用的条件,例如要找出Auto.js脚本列表中名称以"QQ"开头的脚本的代码为textStartsWith(“QQ”).find()。

UiSelector.textEndsWith(suffix)

suffix后缀
为当前选择器附加控件"text需要以suffix结束"的筛选条件。

UiSelector.textMatches(reg)

reg|要满足的正则表达式。
为当前选择器附加控件"text需要满足正则表达式reg"的条件。
有关正则表达式,可以查看正则表达式 - 菜鸟教程。
需要注意的是,如果正则表达式是字符串,则需要使用\来表达(也即Java正则表达式的形式),例如textMatches("\d+")匹配多位数字;但如果使用JavaScript语法的正则表达式则不需要,例如textMatches(/\d+/)。但如果使用字符串的正则表达式则该字符串不能以"/“同时以”/“结束,也即不能写诸如textMatches(”/\d+/")的表达式,否则会被开头的"/“和结尾的”/"会被忽略。

UiSelector.desc(str)

str控件文本
返回返回选择器自身以便链式调用
为当前选择器附加控件"desc等于字符串str"的筛选条件。
控件的desc(描述,全称为Content-Description)属性是对一个控件的描述,例如网易云音乐右上角的放大镜图标的描述为搜索。要查看一个控件的描述,同样地可以借助悬浮窗查看。
desc属性同样是定位控件的利器。

UiSelector.descContains(str)

str要包含的字符串
为当前选择器附加控件"desc需要包含字符串str"的筛选条件。

UiSelector.descStartsWith(prefix)

prefix前缀
为当前选择器附加控件"desc需要以prefix开头"的筛选条件。

UiSelector.descEndsWith(suffix)

suffix后缀
为当前选择器附加控件"desc需要以suffix结束"的筛选条件。

UiSelector.descMatches(reg)

reg|要满足的正则表达式。
为当前选择器附加控件"desc需要满足正则表达式reg"的条件。
有关正则表达式,可以查看正则表达式 - 菜鸟教程。
需要注意的是,如果正则表达式是字符串,则需要使用\来表达(也即Java正则表达式的形式),例如textMatches("\d+")匹配多位数字;但如果使用JavaScript语法的正则表达式则不需要,例如textMatches(/\d+/)。但如果使用字符串的正则表达式则该字符串不能以"/“同时以”/“结束,也即不能写诸如textMatches(”/\d+/")的表达式,否则会被开头的"/“和结尾的”/"会被忽略。

UiSelector.id(resId)

resId控件的id,以"包名:id/“开头,例如"com.tencent.mm:id/send_btn”。也可以不指定包名,这时会以当前正在运行的应用的包名来补全id。例如id(“send_btn”),在QQ界面想当于id(“com.tencent.mobileqq:id/send_btn”)。
为当前选择器附加"id等于resId"的筛选条件。
控件的id属性通常是可以用来确定控件的唯一标识,如果一个控件有id,那么使用id来找到他是最好的方法。要查看屏幕上的控件的id,可以开启悬浮窗并使用界面工具,点击相应控件即可查看。若查看到的控件id为null, 表示该控件没有id。另外,在列表中会出现多个控件的id相同的情况。例如微信的联系人列表,每个头像的id都是一样的。此时不能用id来唯一确定控件。
在QQ界面经常会出现多个id为"name"的控件,在微信上则每个版本的id都会变化。对于这些软件而言比较难用id定位控件。

UiSelector.idContains(str)

strid要包含的字符串
为当前选择器附加控件"id包含字符串str"的筛选条件。比较少用。

UiSelector.idStartsWith(prefix)

prefixid前缀
为当前选择器附加"id需要以prefix开头"的筛选条件。比较少用。

UiSelector.idEndsWith(suffix)

suffixid后缀
为当前选择器附加"id需要以suffix结束"的筛选条件。比较少用。

UiSelector.idMatches(reg)

reg|id要满足的正则表达式
附加id需要满足正则表达式。
需要注意的是,如果正则表达式是字符串,则需要使用\来表达(也即Java正则表达式的形式),例如textMatches("\d+")匹配多位数字;但如果使用JavaScript语法的正则表达式则不需要,例如textMatches(/\d+/)。但如果使用字符串的正则表达式则该字符串不能以"/“同时以”/“结束,也即不能写诸如textMatches(”/\d+/")的表达式,否则会被开头的"/“和结尾的”/“会被忽略。
idMatches(”[a-zA-Z]+")

UiSelector.className(str)

str控件文本
返回返回选择器自身以便链式调用
为当前选择器附加控件"className等于字符串str"的筛选条件。
控件的className(类名)表示一个控件的类别,例如文本控件的类名为android.widget.TextView。
如果一个控件的类名以"android.widget."开头,则可以省略这部分,例如文本控件可以直接用className(“TextView”)的选择器。
常见控件的类名如下:
android.widget.TextView文本控件
android.widget.ImageView图片控件
android.widget.Button按钮控件
android.widget.EditText输入框控件
android.widget.AbsListView列表控件
android.widget.LinearLayout线性布局
android.widget.FrameLayout帧布局
android.widget.RelativeLayout相对布局
android.widget.RelativeLayout相对布局
android.support.v7.widget.RecyclerView通常也是列表控件

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值