1. 程式人生 > >uiautomator中UiObject中getChildCount和getChild方法解惑

uiautomator中UiObject中getChildCount和getChild方法解惑

問題描述

getChildCount得到的子節點數是當前節點的下一層的控制元件數,不包括子節點的子節點。但是用getChild(UiSelector)中遍歷控制元件的時候,把當前節點的子子孫孫全部遍歷一遍。那我就想遍歷當前節點的子節點,怎麼辦?可以傳ClassName進去進行篩選,但是有可能其他手機的每一列並不是又linearLayout來佈局的。所以最好的方法,是一instance遍歷。忽略它是那種className,直接以編號獲得。

實戰

我要遍歷下面圖片所示的介面裡的列表裡的元素,挨個點選。


public void test_DesktopEffects() throws UiObjectNotFoundException {
		uiDevice = getUiDevice();
		width = uiDevice.getDisplayWidth();
		height = uiDevice.getDisplayHeight();
		enterMenu(uiDevice, ValueUtil.DESKTOPEFFECT);

		UiScrollable list = UiUtil.findScrollableByClass(WidgetUtil.LISTVIEW);
		int count = list.getChildCount();
		Log.i(TAG, "count: " + count);
		for (int i = 0; i < count; i++) {
			UiObject child = list.getChild(new UiSelector().instance(i));
			Log.i(TAG, "i: " + i + ", " + child.getBounds().toString());
			child.clickAndWaitForNewWindow();
			uiDevice.pressHome();
			Random random = new Random();
			// 測試時使用1次迴圈,正式使用時,改為10次
			for (int j = 0; j < 1; j++) {

				int index = random.nextInt(2);
				if (index == 0) {
					uiDevice.swipe(width - 48, height / 2, 48, height / 2, 10);
				} else {
					uiDevice.swipe(48, height / 2, width - 48, height / 2, 10);
				}
			}
			if (i < count - 1) {
				enterMenu(uiDevice, ValueUtil.DESKTOPEFFECT);
			}
		}
		uiDevice.pressHome();
	}

列印的log:
04-19 14:48:45.622: I/Idle(5001): count: 7
04-19 14:48:46.162: I/Idle(5001): i: 0, Rect(38, 210 - 502, 306)
04-19 14:48:52.288: I/Idle(5001): i: 1, Rect(62, 230 - 397, 285)
04-19 14:48:58.795: I/Idle(5001): i: 2, Rect(62, 239 - 197, 276)
04-19 14:49:05.731: I/Idle(5001): i: 3, Rect(397, 210 - 487, 306)
04-19 14:49:14.029: I/Idle(5001): i: 4, Rect(397, 210 - 487, 306)
04-19 14:49:20.276: I/Idle(5001): i: 5, Rect(397, 210 - 487, 306)
04-19 14:49:26.572: I/Idle(5001): i: 6, Rect(38, 307 - 502, 403)

從log可以看出,程式遍歷了第一個子元素下面的子元素。且從指令碼執行結果來看,都沒有完全遍歷所有子元素。雖然getChildCount得到了數量,但是真正的物件我們卻無法得到,所以很疑惑google設計初衷。

修改一些程式碼叫獲取元素的方法改為如下:

UiObject child = list.getChild(new UiSelector().clickable(true).instance(i));

執行程式列印Log:

04-19 15:46:53.485: I/Idle(6648): count: 7
04-19 15:46:54.025: I/Idle(6648): i: 0, Rect(38, 210 - 502, 306)
04-19 15:46:59.711: I/Idle(6648): i: 1, Rect(38, 307 - 502, 403)
04-19 15:47:06.417: I/Idle(6648): i: 2, Rect(38, 404 - 502, 500)
04-19 15:47:14.535: I/Idle(6648): i: 3, Rect(38, 501 - 502, 597)
04-19 15:47:21.172: I/Idle(6648): i: 4, Rect(38, 598 - 502, 694)
04-19 15:47:29.790: I/Idle(6648): i: 5, Rect(38, 695 - 502, 791)
04-19 15:47:36.256: I/Idle(6648): i: 6, Rect(38, 792 - 502, 888)

現在點選的點才是正確的。加一個clickable(true),而且控制元件可點選在每一個listview裡的每一個元素都必須要可點選。而且google也要求相互重疊的元素可點選是唯一的。這樣才能好確認焦點。所以這個問題就算解決了