Skip to content

Instantly share code, notes, and snippets.

@vaughandroid
Created August 21, 2015 07:58
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save vaughandroid/e2fda716c7cf6853fa79 to your computer and use it in GitHub Desktop.
Save vaughandroid/e2fda716c7cf6853fa79 to your computer and use it in GitHub Desktop.
An IdlingResource for Espresso which blocks until a View has a particular visibility state.
package com.vaughandroid.test.espresso.idlingresources;
import android.app.Activity;
import android.os.Handler;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.test.espresso.*;
import android.view.View;
import java.lang.ref.WeakReference;
/**
* {@link IdlingResource} which monitors a {@link View} for a given visibility state. The resource is considered idle when the
* View has the desired state.
*
* @author vaughandroid@gmail.com
*/
public class ViewVisibilityIdlingResource implements IdlingResource {
private static final int IDLE_POLL_DELAY_MILLIS = 100;
/** Hold weak reference to the View, so we don't leak memory even if the resource isn't unregistered. */
private final WeakReference<View> mView;
private final int mVisibility;
private final String mName;
private ResourceCallback mResourceCallback;
/**
* @param activity which owns the View
* @param viewId ID of the View to monitor
* @param visibility One of {@link View#VISIBLE}, {@link View#INVISIBLE}, or {@link View#GONE}.
*/
public ViewVisibilityIdlingResource(@NonNull Activity activity, @IdRes int viewId, int visibility) {
this(activity.findViewById(viewId), visibility);
}
/**
* @param view the View to monitor
* @param visibility One of {@link View#VISIBLE}, {@link View#INVISIBLE}, or {@link View#GONE}.
*/
public ViewVisibilityIdlingResource(@NonNull View view, int visibility) {
mView = new WeakReference<View>(view);
mVisibility = visibility;
mName = "View Visibility for view " + view.getId() + "(@" + System.identityHashCode(mView) + ")";
}
@Override
public String getName() {
return mName;
}
@Override
public boolean isIdleNow() {
View view = mView.get();
final boolean isIdle = view == null || view.getVisibility() == mVisibility;
if (isIdle) {
if (mResourceCallback != null) {
mResourceCallback.onTransitionToIdle();
}
} else {
/* Force a re-check of the idle state in a little while.
* If isIdleNow() returns false, Espresso only polls it every few seconds which can slow down our tests.
* Ideally we would watch for the visibility state changing, but AFAIK we can't detect when a View's
* visibility changes to GONE.
*/
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
isIdleNow();
}
}, IDLE_POLL_DELAY_MILLIS);
}
return isIdle;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
mResourceCallback = resourceCallback;
}
}
@Maragues
Copy link

Maybe a view listener such as LayoutChangeListener (view.addOnLayoutChangeListener) or GlobalLayoutListener (view.getViewTreeObserver().addOnGlobalLayoutListener()) can do the trick?

@Emeritus-DarranKelinske

What is the license for this code snippet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment