在更改LayoutParams对象上的属性后,我是否需要再次调用setLayoutParams?

31

我有一个View(包含广告),我需要在某个时间点(广告加载后)将其缩放以适应屏幕宽度。因此,我有一个方法setHeight(myView),该方法计算给定屏幕宽度的正确高度,并相应地更改View的LayoutParams。代码的关键部分如下:

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

这似乎在大部分情况下都有效,但有时视图没有按比例缩放。只有在我在底部添加以下行时,它才能始终正常工作:

myView.setLayoutParams(params);

这似乎也很有道理,因为Android视图在其setLayoutParams()方法中调用requestLayout()。相反,我看不到公共字段(params.height)的更改如何触发布局更改。

另一方面,我经常在网上找到教程,其中参数只是被简单地更改,然后未再次设置到视图中。

所以我的问题是:更改LayoutParams属性后要立即更新布局,是否需要再次调用setLayoutParams?而仅更改属性只会在布局从其他地方触发布局更改时在稍后某个时间点导致布局更改吗?

2个回答

48

只有在下一次布局传递时,布局参数的更改才会生效。

  • requestLayout()安排布局传递

  • setLayoutParams()调用requestLayout(),正如您所观察到的那样

  • 有时通过其他方式安排布局传递。例如,在膨胀后立即对布局参数进行膨胀,并且测量/布局消息刚刚被发布到UI线程消息队列以供稍后处理。

因此,为了安全起见,每次更改布局参数后都要调用requestLayout()setLayoutParams()也可以工作,但在原地修改参数时不是必需的。


既然LayoutParams用于从子视图向父视图通信,那么当子视图的LayoutParams更改时,我们不应该需要在父视图上调用requestLayout吗? - vlazzle
1
@vlazzle 布局请求会向子元素传播到父元素。 - laalto
哦,我在这里看到了:(https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/View.java#L21920)。感谢@laalto! - vlazzle
根据使用情况,您可能希望在UI线程上进行调用。例如:myView.post { myView.layoutParams = params } - Dude

5
在Kotlin中,您可以使用KTX扩展来更新LayoutParams。
view.updateLayoutParams { height = newValue }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接