【发布时间】:2018-01-11 01:19:32
【问题描述】:
我已经有活动使用ViewTreeObserver 没有问题,但在这种情况下我没有收到onGlobalLayout 回调。
由于我在执行 http API 调用后获得了视图的宽度,因此似乎已经计算了宽度(由于 API 调用所花费的时间)。无论如何,为了确保我向ViewTreeObserver 添加了一个侦听器。但有时我没有收到回调(是的,有时)。
我可以在添加监听器之前检查宽度以避免等待回调,但我不知道为什么有时我没有收到回调。我检查了viewTreeObserver 是否始终存在。
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.
});
【问题讨论】: