如何在 Android 或 Android Espresso 中获取视图层次结构

How do you get view hierarchy in Android or Android Espresso

我正在使用 Android Espresso,当它找不到匹配项时,它会在打印视图层次结构时抛出异常。当您在 运行 Android 测试或 Espresso

时,有没有办法动态地获取这种视图层次结构
View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=480, height=800,     has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+->LinearLayout{id=-1, visibility=VISIBLE, width=480, height=800, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
+-->ViewStub{id=16909225, res-name=action_mode_bar_stub, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
|
+-->FrameLayout{id=-1, visibility=VISIBLE, width=480, height=764, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=36.0, child-count=1}
|
+--->ActionBarOverlayLayout{id=2131427395, res-name=decor_content_parent, visibility=VISIBLE, width=480, height=764, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
| 

鉴于 Android View hierarchy 是树结构,使用某种算法更容易遍历每个树节点,您可以在 https://developer.android.com/reference/android/support/test/espresso/util/TreeIterables.html[=15 查看这些方法=]

它打印出异常跟踪的方式使用了一种名为 breadthFirstViewTraversal 的方法,并在 class ViewFinderImpl 中打印出视图树 https://developer.android.com/reference/android/support/test/espresso/base/ViewFinderImpl.html

您可以引发异常并显示视图层次结构。例如把这个放在你的测试文件中:

onView(withText("XYZ")).perform(click())

并且由于文本 XYZ 不存在,结果将是:

...espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "XYZ"

View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=1024, height=600, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}
|
+->LinearLayout{id=-1, visibility=VISIBLE, width=1024, height=600, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
...

HumanReadables.getViewHierarchyErrorMessage 是 Espresso 在视图匹配器失败时用来打印图形的方式,因此与其抛出一个虚假匹配并捕获它,不如:

\ import androidx.test.espresso.util.HumanReadables
val theRootView = fragment.view
val viewHierarchy: String = HumanReadables.getViewHierarchyErrorMessage(theRootView, null, "", null)

您需要一个来传递一个视图。例如,如果您正在使用一个片段,fragment.view 将是图表的根。