如何单击ListView特定行位置中的视图

时间:2015-09-28 12:53:08

标签: android-listview position row android-espresso ui-testing

我有一个ListView:

enter image description here

我想点击ListView中的特定按钮。

如果我想用onData选择器选择:

onData(withId(R.id.button))
                .inAdapterView(withId(R.id.list_view))
                .atPosition(1)
                .perform(click());

我收到了这个错误:

android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id: com.example.application:id/list_view'.
...

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:7)

onData()需要您感兴趣的项目的对象匹配器。如果您不关心适配器中的数据,可以使用Matchers.anything()来有效地匹配中的所有对象。适配器。或者,您可以为项目创建数据匹配器(取决于存储在适配器中的数据)并将其传递给更确定的测试。

至于按钮 - 您要查找的是onChildsView()方法,它允许传递listitem的后代的视图匹配器,该视图匹配器在onData().atPosition()

中匹配

结果你的测试看起来像这样:

    onData(anything()).inAdapterView(withId(R.id.list_view))
            .atPosition(1)
            .onChildView(withId(R.id.button))
            .perform(click());

答案 1 :(得分:0)

我使用了一种不使用ListView数据的解决方法,而.getPosition(index)则检查具有特定id的视图是否是ListView特定位置View的后代。

public static Matcher<View> nthChildsDescendant(final Matcher<View> parentMatcher, final int childPosition) {
    return new TypeSafeMatcher<View>() {
        @Override
        public void describeTo(Description description) {
            description.appendText("with " + childPosition + " child view of type parentMatcher");
        }

        @Override
        public boolean matchesSafely(View view) {

            while(view.getParent() != null) {
                if(parentMatcher.matches(view.getParent())) {
                    return view.equals(((ViewGroup) view.getParent()).getChildAt(childPosition));
                }
                view = (View) view.getParent();
            }

            return false;
        }
    };
}

使用示例:

onView(allOf(
       withId(R.id.button), 
       nthChildsDescendant(withId(R.id.list_view), 1)))
   .perform(click());