Android - View.requestLayout doesn't work in OnLayoutChangeListener

I ran into the same problem. I guess Android has not finished calculating the new layout when onLayoutChanges() is called, and a recalculation cannot be triggered from within the method. The solution is to use a Handler to post layout changes to the end of the UI thread.

I am not really sure about requestLayout(), maybe replace it with another call of setLayoutParams(). It probably has the same effect.

So implement your re-layout in a class implementing Runnable, instantiate a Handler in onCreate() and in onLayoutChanges() instantiate the Runnable class and post it to the Handler:

public class HauptAktivitaet extends Activity implements OnLayoutChangeListener, OnClickListener{

  // this class updates the layout
  private class LayoutUpdater implements Runnable {
    private final int width;
    private final int height;

    private LayoutUpdater(int width, int height) {
      this.width = width;
      this.height = height;
    }

    public void run() {
      mGridLayout_LayoutParams_Above.width = width;
      mGridLayout_LayoutParams_Above.height = height;

      mGridLayout_LayoutParams_Below.width = width;
      mGridLayout_LayoutParams_Below.height = height;

      // might be necessary or not: set layout parameters to trigger update
      mButtonAbove.setLayoutParams(mGridLayout_LayoutParams_Above);   
      mButtonBelow.setLayoutParams(mGridLayout_LayoutParams_Below);
    }
  }

  /* snip */

  // add handler running in UI thread
  private Handler uiHandler;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // instantiate handler
    uiHandler = new Handler();

    inline();

    setContentView(mGridLayout);

  }

  /* snip */

  @Override
  public void onLayoutChange(View v, int left, int top, int right, int bottom,
      int oldLeft, int oldTop, int oldRight, int oldBottom) {

    /* Width and height on this time are known */

    int width = mGridLayout.getWidth();
    int height = mGridLayout.getHeight();

    // post layout update to the end of queue
    uiHandler.post(new LayoutUpdater(width, height / 2);
  }
}

@user3492470
Thank you so much for your answer. I thought nobody has an idea.

Your “solution” is interesting but unfortunately a little bit wrong. Optically it works great but in the background you have got an endless loop …
You will see it if you set a counter at the text of one of the Buttons. The counter increases endlessly.
The setting of Buttons' new layout size in the Handler is followed by a new call of the OnLayoutChangeListener and this Listener starts the Handler again and so on …
You will get the same problem if you are using the OnGlobalLayoutListener instead of the OnLayoutChangeListener with a Handler.
The reason is the following. The view.requestLayout() or view.setLayoutParams(…) does not work in the onLayoutChange method, but it works in the onGlobalLayout method or in a Handler which creates a new thread.
Now the part I really don't understand:
A successful call on the child.requestLayout() makes a new call on the parent's onLayoutChange method. This is peculiar because the parent's layout should not change again.
However that be, a little if/else logic solves the endless calls.

  private int counter = 0;
  @Override
  public void onGlobalLayout() {
    // TODO Auto-generated method stub

    /* Width and height on this time are known */

    int width  = mGridLayout.getWidth();
    int height = mGridLayout.getHeight();

    /* Buttons width and height are supposed to be */

    int mButtons_width  = width;
    int mButtons_height = height / 2;

    if(!(mButtonAbove.getWidth()  == mButtons_width  &&
         mButtonAbove.getHeight() == mButtons_height &&
         mButtonBelow.getWidth()  == mButtons_width  &&
         mButtonBelow.getHeight() == mButtons_height)
      ){

      /* Changes the LayoutParams of ContentViews children dynamicly */

      mGridLayout_LayoutParams_Above.width = mButtons_width;
      mGridLayout_LayoutParams_Above.height = mButtons_height;

      mGridLayout_LayoutParams_Below.width = mButtons_width;
      mGridLayout_LayoutParams_Below.height = mButtons_height;

      /* NO ISSUE ANYMORE:
       * updates the rendering of the buttons */

      mButtonAbove.requestLayout();
      mButtonBelow.requestLayout();

    }

    /* A little debug info for knowing the ContentView's and Children's size */

    mButtonBelow.setText("Own Width = " + mButtonBelow.getWidth() + "\n" + 
                         "Own Height = " + mButtonBelow.getHeight() + "\n" +
                         "Perents Width = " + width + "\n" +
                         "Perents Height = " + height + "\n" +
                         "Calls = " + counter++);

  }

In this case I use the OnGlobalLayoutListener instead of the OnLayoutChangeListener/uiHandler Combination. ;-) The if/else logic is the same.

My original question, why requestLayout does not work in onLayoutChange, is still open but a satisfying solution was presented here so I am happy.

Thank you again for your concern!