Search code examples
androidandroid-espressohorizontal-scrollinghorizontalscrollview

Espresso: How do I scroll to an item in a HorizontalScrollView by index?


This is what my HorizontalScrollView looks like:

<HorizontalScrollView
    android:layout_below="@id/saved_circuits_title"
    android:id="@+id/saved_circuits_scrollview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:id="@+id/saved_circuits_scroll"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
    </LinearLayout>
</HorizontalScrollView>

In my HomeActivity I have the following relevant code that populates the HorizontalScrollView with bitmaps

onCreate{
...
this.savedCircuitsScroll = (LinearLayout) findViewById(R.id.saved_circuits_scroll);
...
}

updateSavedCircuits(){
...// code to make an ImageView from a retrieved bitmap
newImageImage.setOnClickListener(this.thumbnailListener);
this.savedCircuitsScroll.addView(newImageImage);
...
}

How do I use Espresso to scroll to an ImageView at a specified index in my HorizontalScrollView and click it?


What I've tried

I do not have ID's in my layout xml so an approach such as this does not work:

onView( withId( R.id.button)).perform( scrollTo(), click());

I know you can click on an item by index in a RecyclerView and tried finding an analogous approach for HorizontalScrollViews:

    onView(withId(R.id.saved_circuits_scroll))
            .perform(HorizontalScrollViewActions.actionOnItemAtPosition(0, click()));

Except HorizontalScrollViewActions does not exist.

or following this blog I tried the following to at least click an item in the HorizontalScrollView at a specified index:

// Click item at position 3
onView(withHorizontalScrollView(R.id.scroll_view).atPosition(3)).perform(click());
// Convenience helper
public static HorizontalScrollViewMatcher withHorizontalScrollView(final int horizontalScrollViewId) {
    return new HorizontalScrollViewMatcher(horizontalScrollId);
}

except HorizontalScrollViewMatcher does not exist.

What do we do for HorizontalScrollView? It isn't a descendant of ScrollView so the answer here suggests I need to implement my own custom ViewAction. All I want to do is scroll to an item in a HorizontalScrollView by index and click it. Is this really needed? If this is what I need to do, how do I go about implementing this custom ViewAction?



Solution

  • OK so in my particular case I found out that my scroll views had no ID associated with them (or none that I could reach reasonably, hence I couldn't use Mody's answer). However, they did have a tag associated with them so I could use Espresso's withTagValue ViewMatcher instead. Each view was associated with a circuitProject object (of course for you it may be different). And I have access to the following:

    ArrayList<CircuitProject> circuitProjects = new ArrayList<>();
    

    The index of a circuitProject object happens to be the position of the associated view in the HorizontalScrollView. The tag is the folder the circuitProject object is saved to. From here it is straightforward to get the behaviour I need with Espresso scrolling to a particular index in the HorizontalScrollView:

    onView(withTagValue(withStringMatching(circuitProject.getFolderID()))).perform(scrollTo(), click());