问题描述
我有一个 ViewPager
,其中的项目只包含一张图片和一个按钮.
I have a ViewPager
whith items containing only a picture and a button.
我无法与项目(页面)的 UI 成功交互,因为除了显示的图片,没有任何东西可以区分(从 UI 的角度)ViewPager
的所有项目.
I can't successfully interact with the UI of an item (Page) because, except the displayed picture, there is nothing to differentiate (from UI point of view) all items of the ViewPager
.
我试图只选择一个有位置的项目:
I tried to select only one item with a position:
onData(is(instanceOf(ItemClass.class)))
.atPosition(0)
.onChildView(withId(R.id.button))
.perform(click());
原因:
NoMatchingViewException:在层次结构中找不到匹配的视图:可从类分配:类 android.widget.AdapterView
NoMatchingViewException: No views in hierarchy found matching: is assignable from class: class android.widget.AdapterView
如何使用 Espresso 访问和测试 ViewPager
的项目?
How to access and test items of a ViewPager
with Espresso ?
推荐答案
FirstVal, ViewPager
不是AdapterView
,它直接继承自ViewGroup
.所以方法 onData()
不能在 ViewPager
上使用.
FirstVal, ViewPager
is not an AdapterView
, it directly extends from ViewGroup
. So the method onData()
cannot be used on a ViewPager
.
因为它是一个 ViewGroup
,所以每个项目都是其 ViewPager
的直接子项.所以这个过程是使用自定义匹配器引用第一个视图子项(比如这个firstChildOf()
) 并使用 hasDescendant()
和 isDescendantOfA()
访问目标视图并对其执行操作.
As it's a ViewGroup
, each items are direct children of its ViewPager
.
So the process is to reference the first view child using a custom matcher (like this onefirstChildOf()
) and playing with hasDescendant()
and isDescendantOfA()
to access the targeted view and perform an action on it.
onView(allOf(withId(R.id.button), isDescendantOfA(firstChildOf(withId(R.id.viewpager)))))
.perform(click());
解决方案 2(最好)
由于 ViewPager
的特殊性是逐页显示组成它的每个项目(#1 解决方案的子视图).因此,即使您的项目使用具有相同 ID 的相同布局,也只会显示一个.因此我们可以通过其 Id 引用目标视图并添加约束 isDisplayed()
.它将仅匹配一个视图,即当前显示的视图.
Solution 2 (da best)
As the particularity of the ViewPager
is to display each items (#1 solution's child views) that composed it, one by one (page-by-page style). So even if your items use the same layout with the same IDs, only one is displayed. So we can reference the targeted view by its Id and add the constraints isDisplayed()
. It will match only one view, the one that is currently displayed.
onView(allOf(withId(R.id.button), isDisplayed())).perform(click());
就这么简单.
如果你想要另一个项目,你可以执行 swipe()
在您的 ViewPager
上更改显示的项目:
And if you want another item, you may perform a swipe()
on your ViewPager
to change the displayed item:
onView(withId(R.id.viewpager)).perform(swipeLeft());
Android 开发文档中的注释:
isDisplayed 将选择部分显示的视图(例如:视图的整个高度/宽度大于视图的高度/宽度可见的矩形).如果您希望确保整个矩形此视图绘制显示给用户使用 isCompletelyDisplayed()
isDisplayed will select views that are partially displayed (eg: the full height/width of the view is greater than the height/width of the visible rectangle). If you wish to ensure the entire rectangle this view draws is displayed to the user use isCompletelyDisplayed()
谢谢@TWiStErRob
Thanks @TWiStErRob
这篇关于用 Espresso 测试 ViewPager.如何对 Item 的按钮执行操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!