gpt4 book ai didi

android - ViewTreeObserver 不调用 onGlobalLayout

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:54:15 27 4
gpt4 key购买 nike

我已经在使用 ViewTreeObserver 的 Activity 中没有问题,但在这种情况下我没有得到 onGlobalLayout 回调。

由于我在执行 http API 调用后获得了 View 的宽度,因此宽度似乎已经计算出来(由于 API 调用所花费的时间)。无论如何,为了确保我向 ViewTreeObserver 添加了一个监听器。但有时我没有收到回调(是的,有时)。

我可以在添加监听器之前检查宽度以避免必须等待回调,但我不知道为什么有时我没有收到回调。我已经检查过 viewTreeObserver 始终处于 Activity 状态。

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();

assert viewTreeObserver.isAlive();

viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() // Not called sometimes, why?
{
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
doSomething(view.getWidth());
}
});

现在我将使用这个技巧:

int width = view.getWidth();

if (width > 0) {
doSomething(view.getWidth());
} else {
// use the ViewTreeObserver
}

编辑:

为了以防万一,我制作了这个辅助方法:

/**
* Runs code on global layout event, useful when we need to do something after the layout is done
* (like getting the view real measure). The runnable is only called once at most.
*
* A typical `shouldRun` function can be `v -> v.getWidth() > 0` since it checks that the view has some width,
* so we can calculate things depending on that.
*
* @param shouldRun receives the `view` and decides if the runnable should run (it is checked when this method is called, and also on global layout).
*
* See: http://stackoverflow.com/questions/35443681/viewtreeobserver-doesnt-call-ongloballayout
*/
public static void runOnGlobalLayout(final View view, final Func1<View,Boolean> shouldRun, final Runnable runnable)
{
if (shouldRun.call(view)) {
runnable.run();
return;
}

final ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();

if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (shouldRun.call(view)) {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
runnable.run();
}
}
});
}
}

使用该方法,您可以执行以下操作:

runOnGlobalLayout(someLayout, v -> v.getWidth() > 0, () -> {
int availableWidth = someLayout.getWidth();
// draw things in layout, etc.
});

最佳答案

来自关于ViewTreeObserver.OnGlobalLayoutListener的官方文档:

Interface definition for a callback to be invoked when the global layout state or the visibility of views within the view tree changes.

如果您的 http 回调发生在您的 View (及其 subview )的最后一次可见性更改之后,那么您在 OnGlobalLayoutListener 中没有收到任何回调是正常的。

您将获得回调的情况是您的 http 请求在创建所有 View 之前完成,因此您将在 onGlobalLayout 中获得回调,该回调指的是完成绘制 View 。

关于android - ViewTreeObserver 不调用 onGlobalLayout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35443681/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com