UiSelector - 控件操作 2
# UiObject
UiObject表示一个控件,可以通过这个对象获取到控件的属性,也可以对控件进行点击、长按等操作。
获取一个UiObject通常通过选择器的`findOne()`, `findOnce()`等函数,也可以通过UiCollection来获取,或者通过`UiObject.child()`, `UiObject.parent()`等函数来获取一个控件的子控件或父控件。
## UiObject.click()
* 返回 {Boolean}
点击该控件,并返回是否点击成功。
如果该函数返回false,可能是该控件不可点击(clickable为false),当前界面无法响应该点击等。
## UiObject.longClick()
* 返回 {Boolean}
长按该控件,并返回是否点击成功。
如果该函数返回false,可能是该控件不可点击(longClickable为false),当前界面无法响应该点击等。
## UiObject.setText(text)
* `text` {string} 文本
* 返回 {Boolean}
设置输入框控件的文本内容,并返回是否设置成功。
该函数只对可编辑的输入框(editable为true)有效。
## UiObject.copy()
* 返回 {Boolean}
对输入框文本的选中内容进行复制,并返回是否操作成功。
该函数只能用于输入框控件,并且当前输入框控件有选中的文本。可以通过`setSelection()`函数来设置输入框选中的内容。
```
var et = className("EditText").findOne();
//选中前两个字
et.setSelection(0, 2);
//对选中内容进行复制
if(et.copy()){
toast("复制成功");
}else{
toast("复制失败");
}
```
## UiObject.cut()
对输入框文本的选中内容进行剪切,并返回是否操作成功。
该函数只能用于输入框控件,并且当前输入框控件有选中的文本。可以通过`setSelection()`函数来设置输入框选中的内容。
## UiObject.paste()
* 返回 {Boolean}
对输入框控件进行粘贴操作,把剪贴板内容粘贴到输入框中,并返回是否操作成功。
```
//设置剪贴板内容为“你好”
setClip("你好");
var et = className("EditText").findOne();
et.paste();
```
## UiObject.setSelection(start, end)
* `start` {number} 选中内容起始位置
* `end` {number} 选中内容结束位置(不包括)
* 返回 {Boolean}
对输入框控件设置选中的文字内容,并返回是否操作成功。
索引是从0开始计算的;并且,选中内容不包含end位置的字符。例如,如果一个输入框内容为"123456789",要选中"4567"的文字的代码为`et.setSelection(3, 7)`。
该函数也可以用来设置光标位置,只要参数的end等于start,即可把输入框光标设置在start的位置。例如`et.setSelection(1, 1)`会把光标设置在第一个字符的后面。
## UiObject.scrollForward()
* 返回 {Boolean}
对控件执行向前滑动的操作,并返回是否操作成功。
向前滑动包括了向右和向下滑动。如果一个控件既可以向右滑动和向下滑动,那么执行`scrollForward()`的行为是未知的(这是因为Android文档没有指出这一点,同时也没有充分的测试可供参考)。
## UiObject.scrollBackward()
* 返回 {Boolean}
对控件执行向后滑动的操作,并返回是否操作成功。
向后滑动包括了向右和向下滑动。如果一个控件既可以向右滑动和向下滑动,那么执行`scrollForward()`的行为是未知的(这是因为Android文档没有指出这一点,同时也没有充分的测试可供参考)。
## UiObject.select()
* 返回 {Boolean}
对控件执行"选中"操作,并返回是否操作成功。"选中"和`isSelected()`的属性相关,但该操作十分少用。
## UiObject.collapse()
* 返回 {Boolean}
对控件执行折叠操作,并返回是否操作成功。
## UiObject.expand()
* 返回 {Boolean}
对控件执行操作,并返回是否操作成功。
## UiObject.show()
对集合中所有控件执行显示操作,并返回是否全部操作成功。
## UiObject.scrollUp()
对集合中所有控件执行向上滑的操作,并返回是否全部操作成功。
## UiObject.scrollDown()
对集合中所有控件执行向下滑的操作,并返回是否全部操作成功。
## UiObject.scrollLeft()
对集合中所有控件执行向左滑的操作,并返回是否全部操作成功。
## UiObject.scrollRight()
## children()
* 返回 [UiCollection](#widgets_based_automation_uicollection)
返回该控件的所有子控件组成的控件集合。可以用于遍历一个控件的子控件,例如:
```
className("AbsListView").findOne().children()
.forEach(function(child){
log(child.className());
});
```
## childCount()
* 返回 {number}
返回子控件数目。
## child(i)
* i {number} 子控件索引
* 返回 {UiObject}
返回第i+1个子控件。如果i>=控件数目或者小于0,则抛出异常。
需要注意的是,由于布局捕捉的问题,该函数可能返回`null`,也就是可能获取不到某个子控件。
遍历子控件的示例:
```
var list = className("AbsListView").findOne();
for(var i = 0; i < list.childCount(); i++){
var child = list.child(i);
log(child.className());
}
```
## parent()
* 返回 {UiObject}
返回该控件的父控件。如果该控件没有父控件,返回`null`。
## bounds()
* 返回 [Rect](https://hyb1996.github.io/AutoJs-Docs/widgets-based-automation.html#widgets_based_automation_rect)
返回控件在屏幕上的范围,其值是一个[Rect](https://hyb1996.github.io/AutoJs-Docs/widgets-based-automation.html#widgets_based_automation_rect)对象。
示例:
```
var b = text("Auto.js").findOne().bounds();
toast("控件在屏幕上的范围为" + b);
```
如果一个控件本身无法通过`click()`点击,那么我们可以利用`bounds()`函数获取其坐标,再利用坐标点击。例如:
```
var b = desc("打开侧拉菜单").findOne().bounds();
click(b.centerX(), b.centerY());
//如果使用root权限,则用 Tap(b.centerX(), b.centerY());
```
## boundsInParent()
* 返回 [Rect](https://hyb1996.github.io/AutoJs-Docs/widgets-based-automation.html#widgets_based_automation_rect)
返回控件在父控件中的范围,其值是一个[Rect](https://hyb1996.github.io/AutoJs-Docs/widgets-based-automation.html#widgets_based_automation_rect)对象。
## drawingOrder()
* 返回 {number}
返回控件在父控件中的绘制次序。该函数在安卓7.0及以上才有效,7.0以下版本调用会返回0。
## id()
* 返回 {string}
获取控件的id,如果一个控件没有id,则返回`null`。
## text()
* 返回 {string}
获取控件的文本,如果控件没有文本,返回`""`。
## findByText(str)
* `str` {string} 文本
* 返回 [UiCollection](#widgets_based_automation_uicollection)
根据文本text在子控件中递归地寻找并返回文本或描述(desc)**包含**这段文本str的控件,返回它们组成的集合。
该函数会在当前控件的子控件,孙控件,曾孙控件...中搜索text或desc包含str的控件,并返回它们组合的集合。
## findOne(selector)
* `selector` [UiSelector](#widgets_based_automation_uiselector)
* 返回 [UiOobject](#widgets_based_automation_uiobject)
根据选择器selector在该控件的子控件、孙控件...中搜索符合该选择器条件的控件,并返回找到的第一个控件;如果没有找到符合条件的控件则返回`null`。
例如,对于酷安动态列表,我们可以遍历他的子控件(每个动态列表项),并在每个子控件中依次寻找点赞数量和图标,对于点赞数量小于10的点赞:
```
//找出动态列表
var list = id("recycler_view").findOne();
//遍历动态
list.children().forEach(function(child){
//找出点赞图标
var like = child.findOne(id("feed_action_view_like"));
//找出点赞数量
var likeCount = child.findOne(id("text_view"));
//如果这两个控件没有找到就不继续了
if(like == null || likeCount == null){
return;
}
//判断点赞数量是否小于10
if(parseInt(likeCount.text()) < 10){
//点赞
like.click();
}
});
```
## find(selector)
* `selector` [UiSelector](#widgets_based_automation_uiselector)
* 返回 [UiCollection](#widgets_based_automation_uicollection)
根据选择器selector在该控件的子控件、孙控件...中搜索符合该选择器条件的控件,并返回它们组合的集合。
# UiCollection
UiCollection, 控件集合, 通过选择器的`find()`, `untilFind()`方法返回的对象。
UiCollection"继承"于数组,实际上是一个UiObject的数组,因此可以使用数组的函数和属性,例如使用length属性获取UiCollection的大小,使用forEach函数来遍历UiCollection。
例如,采用forEach遍历屏幕上所有的文本控件并打印出文本内容的代码为:
```
console.show();
className("TextView").find().forEach(function(tv){
if(tv.text() != ""){
log(tv.text());
}
});
```
也可以使用传统的数组遍历方式:
```
console.show();
var uc = className("TextView").find();
for(var i = 0; i < uc.length; i++){
var tv = uc[i];
if(tv.text() != ""){
log(tv.text());
}
}
```
UiCollection的每一个元素都是UiObject,我们可以取出他的元素进行操作,例如取出第一个UiObject并点击的代码为`ui[0].click()`。如果想要对该集合的所有元素进行操作,可以直接在集合上调用相应的函数,例如`uc.click()`,该代码会对集合上所有UiObject执行点击操作并返回是否全部点击成功。
因此,UiCollection具有所有UiObject对控件操作的函数,包括`click()`, `longClick()`, `scrollForward()`等等,不再赘述。
## UiCollection.size()
* 返回 {number}
返回集合中的控件数。
历史遗留函数,相当于属性length。
## UiCollection.get(i)
* `i` {number} 索引
* 返回 [UiObject](#widgets_based_automation_uiobject)
返回集合中第i+1个控件(UiObject)。
历史遗留函数,建议直接使用数组下标的方式访问元素。
## UiCollection.each(func)
* `func` {Function} 遍历函数,参数为UiObject。
遍历集合。
历史遗留函数,相当于`forEach`。参考[forEach](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)。
## empty()
* 返回 {Boolean}
返回控件集合是否为空。
## nonEmpty()
* 返回 {Boolean}
返回控件集合是否非空。
## UiCollection.find(selector)
* `selector` [UiSelector](#widgets_based_automation_uiselector)
* 返回 [UiCollection](#widgets_based_automation_uicollection)
根据selector所确定的条件在该控件集合的控件、子控件、孙控件...中找到所有符合条件的控件并返回找到的控件集合。
注意这会递归地遍历控件集合里所有的控件以及他们的子控件。和数组的`filter`函数不同。
例如:
```
var names = id("name").find();
//在集合
var clickableNames = names.find(clickable());
```
## UiCollection.findOne(selector)
* `selector` [UiSelector](#widgets_based_automation_uiselector)
* 返回 [UiOobject](#widgets_based_automation_uiobject)
根据选择器selector在该控件集合的控件的子控件、孙控件...中搜索符合该选择器条件的控件,并返回找到的第一个控件;如果没有找到符合条件的控件则返回`null`。
# Rect
`UiObject.bounds()`, `UiObject.boundsInParent()`返回的对象。表示一个长方形(范围)。
## Rect.left
* {number}
长方形左边界的x坐标、
## Rect.right
* {number}
长方形右边界的x坐标、
## Rect.top
* {number}
长方形上边界的y坐标、
## Rect.bottom
* {number}
长方形下边界的y坐标、
## Rect.centerX()
* 返回 {number}
长方形中点x坐标。
## Rect.centerY()
* 返回 {number}
长方形中点y坐标。
## Rect.width()
* 返回 {number}
长方形宽度。通常可以作为控件宽度。
## Rect.height()
* 返回 {number}
长方形高度。通常可以作为控件高度。
## Rect.contains(r)
* r [Rect](#widgets_based_automation_rect)
返回是否包含另一个长方形r。包含指的是,长方形r在该长方形的里面(包含边界重叠的情况)。
## Rect.intersect(r)
* r [Rect](#widgets_based_automation_rect)
返回是否和另一个长方形相交。