I already have actions in which I use ViewTreeObserver without problems, but in this case I do not get the onGlobalLayout .
Since I get the width of the view after I make the http API call, the width seems to be already calculated (due to the time the API was called). Anyway, so that I add a listener to the ViewTreeObserver . But sometimes I don't get a callback (yes, sometimes).
I can check the width before adding a listener to avoid having to wait for a callback, but I don't know why I sometimes don't get a callback. I checked that ViewTreeObserver always alive.
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver(); assert viewTreeObserver.isAlive(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout()
Now I will use this trick:
int width = view.getWidth(); if (width > 0) { doSomething(view.getWidth()); } else {
EDIT
Just in case this helps, I made this helper method:
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(); } } }); } }
With this method you can do, for example:
runOnGlobalLayout(someLayout, v -> v.getWidth() > 0, () -> { int availableWidth = someLayout.getWidth(); // draw things in layout, etc. });
source share