如何知道一个活动何时完成布局处理?

27

我有一个在onCreate()之后更新活动UI的后台线程。它可以添加布局或更改其他布局的大小。

我希望能够检测到活动中布局完成时的情况,以便能够手动更新其他直接依赖于刚刚添加或修改的布局的视图的位置。

目前,我只是使用一个HandlerpostDelayed runnable来完成这项工作,在触发requestLayout()的修改后小延迟(大约50-100毫秒)。

这种方法可以运行,但显然会有延迟。我想尽快完成这项工作。在视图代码中很容易检测到测量过程,但我不知道如何直接在活动中解决这个问题。

3个回答

49

一个GlobalLayoutListener会在布局完成后触发事件。这是否适合您的需求?

View myView=findViewById(R.id.myView);
  myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //At this point the layout is complete and the 
                //dimensions of myView and any child views are known.
            }
        });

4
我刚刚进行了一项测试,结果显示在初始布局中onGlobalLayout至少被调用了3次。 - ThomasW

2

除了Phillip Fitzsimmons所提供的正确答案,我还想指出,如果有人需要在视图本身中知道尺寸,则可以使用以下方法:

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  // your code here
}

可以被重写,它会在布局处理完成后被调用。


8
虽然这是正确的,但我想补充一下,在某些布局中,可以将其称为两次甚至更多次,其中测量过程将被递归地调用(权重等)。 - JacksOnF1re

1
你可以使用 ViewTreeObserver.OnPreDrawListener,根据文档 https://developer.android.com/reference/android/view/ViewTreeObserver.OnPreDrawListener,在此时,树中的所有视图均已测量并给出了一个框架。只有当树中的某个视图请求另一个布局传递时,任何布局边界才会更改。您也可以使用类似的技术使用 ViewTreeObserver.OnDrawListener 来获取更晚的回调。
myView.getViewTreeObserver().addOnPreDrawListener(
    new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            myView.getViewTreeObserver().removeOnPreDrawListener(this);
            // view is measured and laid out
        });

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