我已经有活动,我正在使用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());
}
});
Run Code Online (Sandbox Code Playgroud)
现在我将使用这个技巧:
int width = view.getWidth();
if (width > 0) {
doSomething(view.getWidth());
} else {
// use the ViewTreeObserver
}
Run Code Online (Sandbox Code Playgroud)
编辑:
为了防止它有用,我制作了这个帮助方法:
/**
* 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();
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
使用该方法,您可以执行以下操作:
runOnGlobalLayout(someLayout, v -> v.getWidth() > 0, () -> {
int availableWidth = someLayout.getWidth();
// draw things in layout, etc.
});
Run Code Online (Sandbox Code Playgroud)
从官方文档ViewTreeObserver.OnGlobalLayoutListener:
当全局布局状态或视图树中视图的可见性发生更改时要调用的回调的接口定义.
如果您的http回调是在视图的最后一次可见性更改(使用他的子视图)之后发生的,那么您没有得到任何回调是正常的OnGlobalLayoutListener.
您将获得回调的情况是您的http请求在创建所有视图之前完成,因此您将获得一个回调,onGlobalLayout这将被称为视图绘制的完成.
| 归档时间: |
|
| 查看次数: |
5879 次 |
| 最近记录: |