how to get the onWindowFocusChanged on Fragment?

From Android 4.3 (API 18) and up you can use this code directly in your Fragment:

Kotlin

view?.viewTreeObserver?.addOnWindowFocusChangeListener { hasFocus -> /*do your stuff here*/ }

or define this extension in your project:

fun Fragment.addOnWindowFocusChangeListener(callback: (hasFocus: Boolean) -> Unit) =
    view?.viewTreeObserver?.addOnWindowFocusChangeListener(callback)

then simply call

addOnWindowFocusChangeListener { hasFocus -> /*do your stuff here*/ }

anywhere in your fragment (just be careful that the root view is still not null at that time).

Note: don't forget to remove your listener when you're done (removeOnWindowFocusChangeListener() method)!


Java

getView().getViewTreeObserver().addOnWindowFocusChangeListener(hasFocus -> { /*do your stuff here*/ });

or without lambda:

getView().getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
    @Override
    public void onWindowFocusChanged(final boolean hasFocus) {
        // do your stuff here
    }
});

Where you can get the non-null View instance in the onViewCreated() method or simply call getView() from anywhere after that.

Note: don't forget to remove your listener when you're done (removeOnWindowFocusChangeListener() method)!


You can either create an interface and all your fragments implement this interface, and inside your onWindowFocusChanged you get the current fragment and pass call the method provided by the interface.

A sample interface for the fragments could be:

public interface IOnFocusListenable {
   public void onWindowFocusChanged(boolean hasFocus);
}

Your fragments have to implement this interface:

public class MyFragment implements IOnFocusListenable {
    ....
    public void onWindowFocusChanged(boolean hasFocus) {
        ...
    }
}

And in the onWindowFocusChanged of your Activity you can then do the following:

public class MyActivity extends AppCompatActivity {
   @Override
   public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if(currentFragment instanceof IOnFocusListenable) {
            ((IOnFocusListenable) currentFragment).onWindowFocusChanged(hasFocus);
        }
    }
}

Or you create a listener and the active fragment is added to the listener. So if the fragment is made visible you subscribe to this listener, and everytime the onWindowFocusChangedevent is called you call this listener.

This approach is very similar to the above with the difference that there is a list of IOnFocusListenable's and those are triggered in the activities onWindowFocusChanged method