Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@Maragues Maragues commented Aug 10, 2016

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

@Emeritus-DarranKelinske

This comment has been minimized.

Copy link

@Emeritus-DarranKelinske Emeritus-DarranKelinske commented Jan 23, 2017

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
You can’t perform that action at this time.