Skip to content

Instantly share code, notes, and snippets.

@davidwong
Created February 3, 2018 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidwong/e695c267fd29d32769b2c3aecb8a4ff0 to your computer and use it in GitHub Desktop.
Save davidwong/e695c267fd29d32769b2c3aecb8a4ff0 to your computer and use it in GitHub Desktop.
RecyclerView update Idling Resource example code
@RunWith(AndroidJUnit4.class)
public class RecyclerViewIdlingResourceTest {
@Rule
public ActivityRule<MainActivity> activityRule = new ActivityRule<MainActivity>(MainActivity.class);
// number of items in the original list
int allItemsCount = ...;
// number of items after the list has been filtered
int filteredItemsCount = ...;
@Test
public void testRecyclerviewFilter()
{
// verify all test items loaded
// SUCCESS
onView(withId(R.id.recyclerview)).check(withItemCount(allItemsCount));
// since the search view is initially collapsed, open it first before tests are run
onView(withId(R.id.action_search)).perform(click());
// enter some text into the search view, and then press the action button.
String searchText = "test"
onView(withId(android.support.design.R.id.search_src_text)).perform(typeText(searchText), pressImeActionButton());
// verify the number of items in the recyclerview list has been altered
// FAIL!
onView(withId(R.id.recyclerview)).check(withItemCount(filteredItemsCount));
}
@Test
public void testRecyclerviewFilterWithPause()
{
// verify all test items loaded
// SUCCESS
onView(withId(R.id.recyclerview)).check(withItemCount(allItemsCount));
// since the search view is initially collapsed, open it first before tests are run
onView(withId(R.id.action_search)).perform(click());
// enter some text into the search view, and then press the action button.
String searchText = "test"
onView(withId(android.support.design.R.id.search_src_text)).perform(typeText(searchText), pressImeActionButton());
// pause for arbitrary period of time, InterruptedException handling left out to simplify example
Thread.sleep(1000);
// verify the number of items in the recyclerview list has been altered
// SUCCESS - assuming the pause time was long enough
onView(withId(R.id.recyclerview)).check(withItemCount(filteredItemsCount));
}
@Test
public void testRecyclerviewFilterWithIdlingResource()
{
// verify all test items loaded
// SUCCESS
onView(withId(R.id.recyclerview)).check(withItemCount(allItemsCount));
// since the search view is initially collapsed, open it first before tests are run
onView(withId(R.id.action_search)).perform(click());
// enter some text into the search view, and then press the action button.
String searchText = "test"
onView(withId(android.support.design.R.id.search_src_text)).perform(typeText(searchText), pressImeActionButton());
// create the idling resource
RecyclerViewLayoutCompleteIdlingResource idlingResource = new RecyclerViewLayoutCompleteIdlingResource((RecyclerViewCallbackContactsActivity) activityTestRule.getActivity());
IdlingRegistry.getInstance().register(idlingResource);
// verify the number of items in the recyclerview list has been altered
// SUCCESS
onView(withId(R.id.recyclerview)).check(withItemCount(filteredItemsCount));
// clean up
IdlingRegistry.getInstance().unregister(idlingResource);
}
}
public interface RecyclerViewLayoutCompleteListener {
// Callback to notify the idling resource that it can transition to the idle state
public void onLayoutCompleted();
}
public interface RecyclerViewIdlingCallback {
public void setRecyclerViewLayoutCompleteListener(RecyclerViewLayoutCompleteListener listener);
public void removeRecyclerViewLayoutCompleteListener(RecyclerViewLayoutCompleteListener listener);
// Callback for the idling resource to check if the resource (in this example the activity containing the recyclerview)
// is idle
public boolean isRecyclerViewLayoutCompleted();
}
public class RecyclerViewLayoutCompleteIdlingResource implements IdlingResource {
private ResourceCallback resourceCallback;
// in this example the RecyclerViewIdlingCallback will be the activity containing the recyclerview
private RecyclerViewIdlingCallback recyclerViewIdlingCallback;
// the listener to add to the resource
private RecyclerViewLayoutCompleteListener listener;
public RecyclerViewLayoutCompleteIdlingResource(RecyclerViewIdlingCallback recyclerViewIdlingCallback){
this.recyclerViewIdlingCallback = recyclerViewIdlingCallback;
// create the listener
listener = new RecyclerViewLayoutCompleteListener() {
@Override
public void onLayoutCompleted() {
if (resourceCallback == null){
return ;
}
//Called when the resource goes from busy to idle.
resourceCallback.onTransitionToIdle();
}
};
// add the listener to the view containing the recyclerview
recyclerViewIdlingCallback.setRecyclerViewLayoutCompleteListener (listener);
}
@Override
public String getName() {
return "RecyclerViewLayoutCompleteIdlingResource";
}
@Override
public boolean isIdleNow() {
return recyclerViewIdlingCallback.isRecyclerViewLayoutCompleted();
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
}
// An example activity to demonstrate using the RecyclerViewLayoutCompleteIdlingResource
public class MainActivity implements SearchView.OnQueryTextListener, ViewTreeObserver.OnGlobalLayoutListener,
RecyclerViewIdlingCallback {
/**
* Flag to indicate if the layout for the recyclerview has complete. This should only be used
* when the data in the recyclerview has been changed after the initial loading.
*/
private boolean recyclerViewLayoutCompleted;
/**
* Listener to be set by the idling resource, so that it can be notified when recyclerview
* layout has been done.
*/
private RecyclerViewLayoutCompleteListener listener;
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_list);
// initialize the recyclerview with original data
// YOUR CODE HERE
setRecyclerViewLayoutCompleted(true);
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@Override
public boolean onQueryTextChange(String query) {
// not used in this example
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
// use the search query to filter the data in the recyclerview,
// followed by a call of notifyDataSetChanged() for the adapter
// YOUR CODE HERE
// flag that a new layout will be required with the filtered data
setRecyclerViewLayoutCompleted(false);
return true;
}
@Override
public void onGlobalLayout() {
if (listener != null)
{
// set flag to let the idling resource know that processing has completed and is now idle
setRecyclerViewLayoutCompleted(true);
// notify the listener (should be in the idling resource)
listener.onLayoutCompleted();
}
}
@Override
public void setRecyclerViewLayoutCompleteListener(RecyclerViewLayoutCompleteListener listener) {
this.listener = listener;
}
@Override
public void removeRecyclerViewLayoutCompleteListener(RecyclerViewLayoutCompleteListener listener) {
if (this.listener != null && this.listener == listener)
{
this.listener = null;
}
}
@Override
public boolean isRecyclerViewLayoutCompleted() {
return recyclerViewLayoutCompleted;
}
public void setRecyclerViewLayoutCompleted(boolean recyclerViewLayoutCompleted) {
this.recyclerViewLayoutCompleted = recyclerViewLayoutCompleted;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment