如何使用Android Espresso点击RecyclerView中的每个项目

时间:2017-06-13 23:37:10

标签: android android-testing android-espresso

有关如何在您输入的任何位置点击RecyclerView中的某个项目的帖子,但是有没有办法点击所有视图,特别是考虑到我可能不知道会有多少视图的事实在Recycler View中。

我想在RecyclerView中获取像in this link这样的项目数量,但它涉及从活动中获取实际的RecyclerView,这有时是不可能的。

我还看到了一段代码:

public static class RecyclerViewItemCountAssertion implements ViewAssertion { private final int expectedCount;

    public RecyclerViewItemCountAssertion(int expectedCount) {
        this.expectedCount = expectedCount;
    }

    @Override
    public void check(View view, NoMatchingViewException noViewFoundException) {
        if (noViewFoundException != null) {
            throw noViewFoundException;
        }

        RecyclerView recyclerView = (RecyclerView) view;
        RecyclerView.Adapter adapter = recyclerView.getAdapter();
        assertThat(adapter.getItemCount(), is(expectedCount));
    }
}

但我不确定如何操纵以获得计数

3 个答案:

答案 0 :(得分:1)

所以简单地在你的测试中:

final View viewById = activityTestRule.getActivity().findViewById(R.id.your_recycler_view_id);
final RecyclerView recyclerView = (RecyclerView) viewById;
final RecyclerView.Adapter adapter = recyclerView.getAdapter();
final int itemsCount = adapter.getItemCount();

因此,您可以从0itemsCount-1

进行迭代

您可以使用此类在位置(在您的情况下为0 to itemsCount-1)获取回收站视图元素

public class RecyclerViewMatcher {
private final int recyclerViewId;

public RecyclerViewMatcher(int recyclerViewId) {
    this.recyclerViewId = recyclerViewId;
}

public Matcher<View> atPosition(final int position) {
    return atPositionOnView(position, -1);
}

public Matcher<View> atPositionOnView(final int position, final int targetViewId) {

    return new TypeSafeMatcher<View>() {
        Resources resources = null;
        View childView;

        public void describeTo(Description description) {
            String idDescription = Integer.toString(recyclerViewId);
            if (this.resources != null) {
                try {
                    idDescription = this.resources.getResourceName(recyclerViewId);
                } catch (Resources.NotFoundException var4) {
                    idDescription = String.format("%s (resource name not found)", recyclerViewId);
                }
            }

            description.appendText("with id: " + idDescription);
        }

        public boolean matchesSafely(View view) {

            this.resources = view.getResources();

            if (childView == null) {
                RecyclerView recyclerView =
                        (RecyclerView) view.getRootView().findViewById(recyclerViewId);
                if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
                    childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
                } else {
                    return false;
                }
            }

            if (targetViewId == -1) {
                return view == childView;
            } else {
                View targetView = childView.findViewById(targetViewId);
                return view == targetView;
            }
        }
    };
}}

并像这样使用这个类:

onView(new RecyclerViewMatcher(R.id.your_recycler_view_id)
            .atPositionOnView(0, R.id.your_item_body))
            .perform(click());

最后,您可以点击recyclerview中的所有项目。我希望它会有所帮助。欢呼声。

答案 1 :(得分:0)

我在这里大声思考,但我会尝试的几件事情是: a-检查是否有任何方法将其放入ViewHolder / RecyclerView适配器中。这真的取决于你想要触发所有项目的点击时所以我猜它不适合你。
b-尝试使用try / catch获取项目的while循环。从软件工程最佳实践的角度来看,这听起来并不是一个好主意,但如果您的目标只是为了让某些工作正常,那么它应该可行。
c-如果您无法获得回收站视图本身,您是否可以通过某种方式访问​​用于填充recyclerView本身的arraylist(或其他)?

有些问题:
1-在什么情况下您无法获得实际的回收者视图?如果你不能得到它,那你怎么会触发它的onclick呢?
2-您可以分享您的代码以及您需要执行此操作的位置吗?

免责声明:我对Android开发有点新意,但我希望这会有所帮助。

答案 2 :(得分:0)

为了保证线程安全,您应该使用类似

的自定义视图操作
@RunWith(AndroidJUnit4.class)
public class XXXXActivityTest {

int count=0;

@Test
public void xxxxxxx() throws Exception {
    onView(allOf(withId(R.id.drawer_list))).perform(new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return null;
        }

        @Override
        public String getDescription() {
            return null;
        }

        @Override
        public void perform(UiController uiController, View view) {
            count=((ListView)view).getAdapter().getCount();
        }
    });

}
}

然后你可以用

进行迭代
onView(new RecyclerViewMatcher(R.id.drawer_list)
        .atPositionOnView(0, R.id.your_item_body))
        .perform(click());
assertThat(.......) for all items