我正在尝试识别ui元素的父视图,以便我可以自由地浏览UI。
例如,在“设置”应用中,我可以找到带有“蓝牙”文字的视图:
UiObject btView = new UiObject(new UiSelector().text("Bluetooth"));
现在,我遇到困难的部分是这样的:我想要向上导航两个级别并开始新的搜索开启/关闭按钮,启用和禁用蓝牙。
注意:如果我使用下面的代码,我可以获得该按钮。
UiObject btButtonView = new UiObject(new UiSelector().className("android.widget.Switch").instance(1));
这将搜索切换按钮并返回第二次遭遇。我希望搜索更精确,并在线性布局中查找包含“蓝牙”文本的按钮。
更新: 这是“设置”应用程序(我需要的蓝牙部分)的布局:
LinearLayout
LinearLayout
ImageView
RelativeLayout
TextView (with text = "Bluetooth")
Switch ()
答案 0 :(得分:15)
您需要首先使用文本找到UiObject两个级别。这可以使用UiCollection或UiScrollable中的getChildByText()
方法完成。然后你可以很容易地找到开关。对于“设置”,此代码适用于我的设备:
UiScrollable settingsList = new UiScrollable(new UiSelector().scrollable(true));
UiObject btItem = settingsList.getChildByText(new UiSelector().className(LinearLayout.class.getName()),"Bluetooth", true);
UiObject btSwitch = btItem.getChild(new UiSelector().className(android.widget.Switch.class.getName()));
btSwitch.click();
答案 1 :(得分:4)
下面的代码适合我。
//Getting the scrollable view
UiScrollable settingsList = new UiScrollable(new UiSelector().scrollable(true));
for (int i=0; i<=settingsList.getChildCount(new UiSelector ().className(LinearLayout.class.getName())); i++) {
//Looping through each linear layout view
UiObject linearLayout = settingsList.getChild(new UiSelector().className(LinearLayout.class.getName()).instance(i));
//Checking if linear layout have the text. If yes, get the switch, click and break out of the loop.
if (linearLayout.getChild(new UiSelector ().text("Bluetooth")).exists()) {
UiObject btSwitch = linearLayout.getChild(new UiSelector().className(android.widget.Switch.class.getName()));
btSwitch.click ();
break;
}
}
答案 2 :(得分:0)
如果您只想搜索ON / OFF滑块 - &gt;您可以直接搜索蓝牙OFF / ON按钮并单击它以禁用/启用蓝牙 -
您可以在命令提示符下查看蓝牙页面的屏幕截图(使用命令 - uiautomatorviewer),并看到OFF按钮在OFF / ON滑块中有文本。然后只需使用 -
new UiObject(new UiSelector().text("OFF")).click();
答案 3 :(得分:0)
最近发现我们可以使用getFromParent(对于UiObject)和fromParent(对于UiSelector)来选择对象的叔叔。 如果我们有这样的布局:
`LinearLayout
relative layout
text View
relative layout
check box`
我们可以使用以下代码从textview获取复选框:
TextViewTitle().getFromParent(new UiSelector()
.fromParent(new UiSelector()
.resourceId("android:id/checkbox")));
其中TextViewTitle是带有文本视图的Uiobject
答案 4 :(得分:0)
uiautomator
不支持:直接获取父节点
但是您可以自己添加(这需要很多工作)
一般步骤:
xpath
添加uiautomator
xpath
查找父节点d.xpath("/current_node_path/..")
其他节点:
我使用
uiautomator2
基于xiaocong/uiautomator
通过以下方法成功找到父节点:
self.driver.xpath("//android.widget.TextView[@text='Contact']/..")
和完整代码:
def isMatchNode(self, curNodeAttrib, toMathInfo):
isAllMatch = True
for eachKey, eachToMatchValue in toMathInfo.items():
if eachKey not in curNodeAttrib:
isAllMatch = False
break
curValue = curNodeAttrib[eachKey]
if curValue != eachToMatchValue:
isAllMatch = False
break
return isAllMatch
def findParentNode(self, curNodeXpath, matchDict, maxUpLevel=3):
matchNode = None
curNode = self.driver.xpath(curNodeXpath).get()
curNodeAttrib = curNode.attrib # .attrib contain 'clickable'
# curNodeInfo = curNode.info # .info not contain 'clickable'
isCurMatch = self.isMatchNode(curNodeAttrib, matchDict)
if isCurMatch:
# current is match
matchNode = curNode
else:
# try parent nodes
curUpLevel = 1
curParentNodeXpath = curNodeXpath
hasFound = False
while((not hasFound) and (curUpLevel <= maxUpLevel)):
curParentNodeXpath += "/.."
curParentNode = self.driver.xpath(curParentNodeXpath).get()
curParentNodeAttrib = curParentNode.attrib
isCurParentMatch = self.isMatchNode(curParentNodeAttrib, matchDict)
if isCurParentMatch:
matchNode = curParentNode
break
return matchNode
def location_WexinAdd(self, reload=False):
for eachNodeText in ["Contact", "Public Account"]:
eachNodeXpath = "//android.widget.TextView[@text='%s']" % eachNodeText
matchDict = {"clickable": "true"}
clickableParentNode = self.findParentNode(curNodeXpath=eachNodeXpath, matchDict=matchDict)
if clickableParentNode:
clickableParentNode.click()
else:
logging.warning("Fail click %s for not found clickable=true (parent) node", eachNodeText)
供您参考。