How to know when the RecyclerView has finished laying down the items? How to know when the RecyclerView has finished laying down the items? android android

How to know when the RecyclerView has finished laying down the items?


I also needed to execute code after my recycler view finished inflating all elements. I tried checking in onBindViewHolder in my Adapter, if the position was the last, and then notified the observer. But at that point, the recycler view still was not fully populated.

As RecyclerView implements ViewGroup, this anwser was very helpful. You simply need to add an OnGlobalLayoutListener to the recyclerView:

View recyclerView = findViewById(R.id.myView);recyclerView    .getViewTreeObserver()    .addOnGlobalLayoutListener(        new ViewTreeObserver.OnGlobalLayoutListener() {            @Override            public void onGlobalLayout() {                // At this point the layout is complete and the                // dimensions of recyclerView and any child views                 // are known.                recyclerView                    .getViewTreeObserver()                    .removeOnGlobalLayoutListener(this);            }        });


Working modification of @andrino anwser.

As @Juancho pointed in comment above. This method is called several times. In this case we want it to be triggered only once.

Create custom listener with instance e.g

private RecyclerViewReadyCallback recyclerViewReadyCallback;public interface RecyclerViewReadyCallback {    void onLayoutReady();}

Then set OnGlobalLayoutListener on your RecyclerView

recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {            @Override            public void onGlobalLayout() {                if (recyclerViewReadyCallback != null) {                    recyclerViewReadyCallback.onLayoutReady();                }                recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);            }        });

after that you only need implement custom listener with your code

recyclerViewReadyCallback = new RecyclerViewReadyCallback() {             @Override             public void onLayoutReady() {                 //                 //here comes your code that will be executed after all items are laid down                 //             }};


If you use Kotlin, then there is a more compact solution.Sample from here.
This layout listener is usually used to do something after a View is measured, so you typically would need to wait until width and height are greater than 0.
... it can be used by any object that extends View and also be able to access to all its specific functions and properties from the listener.

// define 'afterMeasured' layout listener:inline fun <T: View> T.afterMeasured(crossinline f: T.() -> Unit) {    viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {        override fun onGlobalLayout() {            if (measuredWidth > 0 && measuredHeight > 0) {                viewTreeObserver.removeOnGlobalLayoutListener(this)                f()            }        }    })}// using 'afterMeasured' handler:myRecycler.afterMeasured {    // do the scroll (you can use the RecyclerView functions and properties directly)    // ...}