How to detect a layout resize?

Override onSizeChanged in your View!


With Kotlin extensions:

inline fun View?.onSizeChange(crossinline runnable: () -> Unit) = this?.apply {
    addOnLayoutChangeListener { _, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
        val rect = Rect(left, top, right, bottom)
        val oldRect = Rect(oldLeft, oldTop, oldRight, oldBottom)
        if (rect.width() != oldRect.width() || rect.height() != oldRect.height()) {
            runnable();
        }
    }
}

Use thus:

myView.onSizeChange { 
     // Do you thing...
}

My solution is to add an invisible tiny dumb view at the end of of the layout / fragment (or add it as a background), thus any change on size of the layout will trigger the layout change event for that view which could be catched up by OnLayoutChangeListener:

Example of adding the dumb view to the end of the layout:

 <View 
    android:id="@+id/theDumbViewId"
    android:layout_width="1dp"
    android:layout_height="1dp"
     />

Listen the event:

    View dumbView = mainView.findViewById(R.id.theDumbViewId);
    dumbView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            // Your code about size changed
        }
    });

One way is View.addOnLayoutChangeListener. There's no need to subclass the view in this case. But you do need API level 11. And the correct calculation of size from bounds (undocumented in the API) can sometimes be a pitfall. Here's a correct example:

view.addOnLayoutChangeListener( new View.OnLayoutChangeListener()
{
    public void onLayoutChange( View v,
      int left,    int top,    int right,    int bottom,
      int leftWas, int topWas, int rightWas, int bottomWas )
    {
        int widthWas = rightWas - leftWas; // Right exclusive, left inclusive
        if( v.getWidth() != widthWas )
        {
            // Width has changed
        }
        int heightWas = bottomWas - topWas; // Bottom exclusive, top inclusive
        if( v.getHeight() != heightWas )
        {
            // Height has changed
        }
    }
});

Another way (as dacwe answers) is to subclass your view and override onSizeChanged.