Custom RecyclerView's LayoutManager. Automeasuring after animation finished on item delete

I've at last figured it out. So, my solution:

Subscribe to dataChanges event in onAdapterChanged method and disable automeasuring.

 @Override
public void onAdapterChanged(RecyclerView.Adapter oldAdapter,
                             RecyclerView.Adapter newAdapter) {
    newAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            // on api 16 this is invoked before onItemsRemoved
            super.onItemRangeRemoved(positionStart, itemCount);
            /** we detected removing event, so should process measuring manually
             */
            setAutoMeasureEnabled(false);
        }
    });
     //Completely scrap the existing layout
    removeAllViews();
}

In onMeasure in case auto-measuring disabled measure manually, use current size:

 @Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
    super.onMeasure(recycler, state, widthSpec, heightSpec);

    if (!isAutoMeasureEnabled()) {
        // we should perform measuring manually
        // so request animations
        requestSimpleAnimationsInNextLayout();
        //keep size until remove animation will be completed
        setMeasuredDimension(getWidth(), getHeight());
    }
}

Perform auto-measuring after animation finished:

 @Override
public void onItemsRemoved(final RecyclerView recyclerView, int positionStart, int itemCount) {
    super.onItemsRemoved(recyclerView, positionStart, itemCount);
    //subscribe to next animations tick
    postOnAnimation(new Runnable() {
        @Override
        public void run() {
            //listen removing animation
            recyclerView.getItemAnimator().isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
                @Override
                public void onAnimationsFinished() {
                    //when removing animation finished return auto-measuring back
                    setAutoMeasureEnabled(true);
                    // and process onMeasure again
                    requestLayout();
                }
            });
        }
    });

This callbacks chain is safe, because postOnAnimation runnable won't be executed in case layout manager is detached from RecyclerView


@Beloo's answer was not working for me, I suspect because setAutoMeasureEnabled has been deprecated. I was able to get it working by only overriding onItemsRemoved, onMeasure and also isAutoMeasureEnabled.

First create a variable that will keep track of the isAutoMeasureEnabled property:

private boolean autoMeasureEnabled = true;

Then override isAutoMeasureEnabled to use the variable:

@Override
public boolean isAutoMeasureEnabled (){
    return autoMeasureEnabled;
}

Now you can set the variable autoMeasureEnabled at will. Override onItemsRemoved:

@Override
public void onItemsRemoved(@NonNull final RecyclerView recyclerView, int positionStart, int itemCount) {
    super.onItemsRemoved(recyclerView, positionStart, itemCount);
    autoMeasureEnabled = false;
    postOnAnimation(new Runnable() {
        @Override
        public void run() {
            recyclerView.getItemAnimator().isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
                @Override
                public void onAnimationsFinished() {
                    autoMeasureEnabled = true;
                    requestLayout();
                }
            });
        }
    });
}

Also override onMeasure just like in @Beloo's answer:

    @Override
public void onMeasure(@NotNull RecyclerView.Recycler recycler, @NotNull RecyclerView.State state, int widthSpec, int heightSpec) {
    super.onMeasure(recycler, state, widthSpec, heightSpec);

    if (!isAutoMeasureEnabled()) {
        // we should perform measuring manually
        // so request animations
        requestSimpleAnimationsInNextLayout();
        //keep size until remove animation will be completed
        setMeasuredDimension(getWidth(), getHeight());
    }
}

This seems to work. The animation is fast, but timed correctly.