After changing a property on a LayoutParams object, do I need to call setLayoutParams again?

david.mihola picture david.mihola · Oct 16, 2014 · Viewed 11.1k times · Source

I have a View (containing an ad) that I need to scale to fit the screen width at a certain point in time (after the ad is loaded). So I have a method setHeight(myView) that calculates the correct height for the given screen width and changes the LayoutParams of the View accordingly. The crucial part of the code is this:

LayoutParams params = myView.getLayoutParams();
int width = myView.getWidth();
if (params != null && width > 0) {
    params.height = (int) Math.round(ratio * width);
}

This seems to work for the most part, but sometimes the view is not scaled. It seems to only consistenly work if I add the following line at the bottom:

myView.setLayoutParams(params);

This seems to make sense, too, since Android Views call requestLayout() in their setLayoutParams() method. Conversely, I see no way how a change in a public field (params.height) would trigger a layout change.

On the other hand, I repeatedly find tutorials on the net where the params are simply changed and then not set to the view again.

So, my question is: Is it correct that, to immediately update the layout after changing a property of the LayoutParams, I need to call setLayoutParams again? And that simply changing the property will only lead to a layout change at some later point in time when the layout change is triggered from elsewhere?

Answer

laalto picture laalto · Oct 16, 2014

A change to the layout params only take effect on the next layout pass.

  • requestLayout() schedules a layout pass

  • setLayoutParams() calls requestLayout() as you have observed

  • Sometimes a layout pass is scheduled by some other means. For example, immediately after inflation the layout params have also been inflated and the measure/layout message has just been posted to the UI thread message queue for later processing.

So, to be safe, call requestLayout() always after touching the layout params. setLayoutParams() works, too, though it's not strictly necessary when modifying the params in-place.