Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Espresso : Recyclerview scroll to end

Is there a way to scroll to the end of recyclerview using Espresso?

There is an item with text let's say 'Text XYZ' and the recyclerview has an id recycler_view. This item happens to be the last item of the recycler view.

I tried

onView(withId(R.id.recycler_view)).check(matches(isDisplayed())).perform(RecyclerViewActions.scrollTo(withText("Text XYZ")),click());

But this doesn't seem to work. Any ideas?

like image 279
Shikhar Shrivastav Avatar asked Sep 03 '16 11:09

Shikhar Shrivastav


2 Answers

RecyclerViewActions.scrollTo() matches against the ItemView of the ViewHolder, which is inflated in onCreateViewHolder() of the adapter. And in order for the scrollTo() to work, you need to provide a matcher that uniquely identifies that ItemView.

Your current matcher tells espresso to scroll to a ViewHolder that was inflated with a TextView as an itemView. Which can happen, but usually you have some ViewGroup action going on there to style the view holders in the way you want them to look.

If you change your scrollTo() Matcher, to hasDescendant(withText("Text XYZ")) to account for all nested layouts (if there more than one).

Also keep in mind since you are also trying to click the item - you can't do it in the same perform() because it will send the click to the current ViewInteraction, which is in this case a RecyclerView with id R.id.recycler_view. Doing so in the same perform just clicks the middle on the RecyclerView, not the item that you scrolled to.

To solve this you need either need another onView() with the matcher that you used to scroll to an item or use RecyclerView.actionOnItem().

In case of another onView() statement, the hasDescendant(withText("Text XYZ")) will fail you, because it will find all parents of that TextView (viewholder, recyclerview, the viewgroup that holds the recyclerview and so on) as they all have this particular descendant. This will force you to make the ItemView matcher to be more precise and account for all nested layouts. My usual go to matcher is withChild() in these situations, but it might be different for you.

like image 104
Be_Negative Avatar answered Nov 06 '22 08:11

Be_Negative


If you know the last position of the RecyclerView, then you can scroll to it

static final int LAST_POSITION = 100;

// First method
onView(withId(R.id.recyclerview))
    .perform(RecyclerViewActions.scrollToPosition((LAST_POSITION)));

// Second method
onView(withId(R.id.recyclerview))
        .perform(actionOnItemAtPosition(LAST_POSITION, scrollTo()));
like image 2
Zain Avatar answered Nov 06 '22 08:11

Zain