什么时候我们知道Activity的视图已经布局完成?

5

我有一个带以下视图层次结构的活动:

<RelativeLayout>
    <LinearLayout>
        <GridLayout />
    </LinearLayout>
</RelativeLayout>

顶部的RelativeLayout占据整个屏幕,而LinearLayout占据屏幕的一部分。我试图以这样的方式设置GridLayout子视图的大小,即对于n行和m列,单元格的大小直接与n、m值以及LinearLayout的宽度和高度相关联。
因此,例如,我正在尝试按以下方式获取单元格的宽度和高度:
int linearLayoutWidth = mLinearLayout.getMeasuredWidth();
int linearLayoutHeight = mLinearLayout.getMeasuredHeight();
...

int rows = mGridModel.getRows() + 1;
int columns = mGridModel.getColumns() + 1;
int cellWidth = (int) (linearLayoutWidth / columns);
int cellHeight = (int) (linearLayoutHeight / rows);

很不幸,当视图被创建时,mLinearLayout.getMeasuredWidth()不能返回正确的大小。它总是返回实际设备屏幕的宽度,直到视图完全布局完成 - 在这种情况下为时已晚。我已经根据最初完全不正确的值为我的子单元视图设置了大小。
我的问题是 - 我如何知道视图何时完全布局。我需要查询它们的正确或实际测量宽度/高度。
setContentView()创建视图并理论上将它们布局。但是视图不能保证在最终的正确位置/大小。
2个回答

11

您可以将ViewObserver添加到任何视图中,在此观察者中有一个回调方法onGlobalLayout,当布局已完成时调用。

ViewTreeObserver observer = view.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //in here, place the code that requires you to know the dimensions.


         //this will be called as the layout is finished, prior to displaying.
    }
}

对我来说并不不幸 - 这似乎是一个优雅的方式来了解布局正在做什么。 - Caspar Harmer
是的,这是一种优雅的方式来了解布局正在做什么。 - mdupls
6
在一个 Activity 中使用 onLayoutSet 方法会是一种更加优雅的方式。 - zmbq

2
扩展jeet的答案,您可以使您的活动实现该侦听器,这将导致稍微更好的代码。
public class MyActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        view.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        ...
    }

}

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