@Override
  public void click() {
    waitUntilIsDisplayed();
    scrollIntoScreenIfNeeded();

    final View view = getView();
    final int[] xy = new int[2];

    try {
      Thread.sleep(300);
    } catch (InterruptedException e) {
      // No-op
    }
    view.getLocationOnScreen(xy);
    if (Build.VERSION.SDK_INT < 19 || xy[0] !=0 && xy[1] != 0) {
      doClick();
      return;
    }

    if (view.isLaidOut()) {
      SelendroidLogger.debug("View is laid out, clicking immediately");
      doClick();
      return;
    }

    final AndroidWait wait = instrumentation.getAndroidWait();
    final AtomicBoolean isLaidOut = new AtomicBoolean(false);
    final ViewTreeObserver observer = view.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        try {
          isLaidOut.set(true);
        } finally {
          if (observer.isAlive()) {
            removeOnGlobalLayoutListener(observer, this);
          } else {
            removeOnGlobalLayoutListener(view.getViewTreeObserver(), this);
          }
        }
      }
    }); 
    try {
      wait.until(new Function<Void, Boolean>() {
        @Override
        public Boolean apply(Void input) {
          return isLaidOut.get();
        }
      });
    } catch (TimeoutException e) {
      throw new SelendroidException("View was never laid out", e);
    }

    doClick();
  }
If view.isShown() == false, logs why exactly this evaluates to false.
Copied from Android's implementation of View.isShown().
selendroid-server/src/main/java/io/selendroid/server/model/AndroidNativeElement.java