Listener to detect whether a view is at the front?

2.1k views Asked by At

I have RecyclerView and, in some cases, I show another view on top of it - ProgressDialog, AlertDialog or DialogFragment.

Is there some way to notify me about cases when my RecyclerView is at front or another view is above it now?

I tried to add onFocusChangeListener() to my RecyclerView, but no luck.

PS. Definitely, I can in my RecyclerView create some method isOnFront(boolean onFront) and in all my other views call it, but maybe there is some more elegance way?

2

There are 2 answers

3
azizbekian On BEST ANSWER

ProgressDialog, AlertDialog and DialogFragment would lay their content on the Window, not to your activity's/fragment's view hierarchy. Which means, that as soon as either of them is shown, the focus of Window is changed. Hence, you can make use of ViewTreeObserver#addOnWindowFocusChangeListener() API:


    contentView.getViewTreeObserver().addOnWindowFocusChangeListener(
        new ViewTreeObserver.OnWindowFocusChangeListener() {
          @Override public void onWindowFocusChanged(boolean hasFocus) {
            // Remove observer when no longer needed
            // contentView.getViewTreeObserver().removeOnWindowFocusChangeListener(this);

            if (hasFocus) {
              // Your view hierarchy is in the front
            } else {
              // There is some other view on top of your view hierarchy,
              // which resulted in losing the focus of window
            }
          }
        });

0
artkoenig On

I think you should rethink your software design. If YOU trigger dialogs to be shown on top of another views, then you SHOULD know if the are shown or not. Another question is: Why should your RecyclerView know something about other views in your application?

If you really want to know, if your dialog is shown or not, set a boolean variable in your Fragment (or Activity), when you show it. Or use the field itself as indicator (myDialog != null equals "myDialog is shown"). Set it to null if you dismiss your dialog. If you really need to let other Fragments or Views know, that you show a dialog on top of them you can use any kind of event bus to broadcast this event.

I do not recommend tampering with any kind of ViewTreeObserver listeners or FragmentBackstack listeners for getting this result.