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

2

32

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?

Gunflint answered 16/10, 2014 at 7:5 Comment(0)
C
48

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.

Cyrenaic answered 16/10, 2014 at 7:9 Comment(4)
Since LayoutParams are used to communicate from the child to the parent, shouldn't we need to call requestLayout on the parent once the child's LayoutParams change?Asserted
@Asserted Layout requests on children propagate to the parent as well.Cyrenaic
Oh yeah I see that here. Thanks @laalto!Asserted
Depending on the use case, you may want to do that call on the UI thread. e.g. myView.post { myView.layoutParams = params }Significant
L
6

In Kotlin you can use KTX extension to update LayoutParams

view.updateLayoutParams { height = newValue }
Lx answered 22/7, 2021 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.