FrameLayout子视图在调整大小时未正确更新

时间:2016-01-27 15:40:07

标签: android android-framelayout

我有一个Android应用程序,根视图是FrameLayout,它在轮换时保留并调整大小而不是重新创建。

FrameView的孩子中有一个自定义View(主视图)占据了整个空间,另一个自定义View我要显示为一个窄带沿底边(纵向模式)或右边(横向模式)。

为此,我从主视图的onSizeChanged()方法运行以下代码:

boolean isBandShowing = ...;    // whether the band should be shown
boolean isPortrait = ...;       // whether we are in portrait mode, controls where the band is displayed
int horizontalBandHeight = ...; // default height for band in portrait mode
int verticalBandWidth = ...;    // default width for band in landscape mode

bandView.setVisibility(isBandShowing ? View.VISIBLE : View.GONE);
LayoutParams bandLayoutParams = new FrameLayout.LayoutParams(
    isPortrait ? LayoutParams.MATCH_PARENT : verticalBandWidth,  // X
    isPortrait ? horizontalBandHeight : LayoutParams.MATCH_PARENT, // Y
    Gravity.BOTTOM | Gravity.RIGHT);
bandView.setLayoutParams(bandLayoutParams);

创建后,onSizeChanged()被调用一次(在日志输出中可见)并按预期设置频段。

然而,当旋转显示器时,乐队的位置未正确更新。从纵向旋转到横向后,乐队仍显示在底部。当我旋转回肖像时,乐队向右移动 - 它一直落后。

添加一些日志输出,我可以看到以下内容:

    每次轮换都会调用
  • onSizeChanged()
  • 顶部的四个变量具有正确的值(纵向/横向正确反映新的方向)
  • 如果我从新创建的LayoutParams查询宽度和高度,则它们具有预期值
  • 如果我在调用bandView后立即查询setLayoutParams()的尺寸,则会显示旧值(如旋转前显示)。

我尝试了一些事情,但无济于事:

  • requestLayout()和乐队视图
  • 上调用FrameLayout
  • 同时调用invalidate()
  • 同时调用postInvalidate()
  • 在设置新bandView之前从FrameLayout删除LayoutParams,然后重新添加

是什么给出了?

1 个答案:

答案 0 :(得分:1)

正如我基于日志输出所怀疑的那样,在调用时onSizeChanged()时,UI内容中的某些内容尚未更新。我还没弄清楚是什么,但需要注意的是LayoutParams的东西需要延期,直到其他所有东西都完成了。这可以通过将代码包装到Runnable的{​​{1}}和post()来完成:

FrameLayout

解决了它。