I\'m trying to get the height and width of an ImageView in a Fragment with the following ViewTreeObserver:
import andr
Better try to check if a getViewTreeObserver is alive. I think the following code will work. Based on https://stackoverflow.com/a/15301092/2914140, https://stackoverflow.com/a/26193736/2914140 and some others.
** Update **
After reading Remove listener from ViewTreeObserver, https://stackoverflow.com/a/40013262/2914140 I rewrote a bit.
public static void captureGlobalLayout(@NonNull final View view,
@NonNull final ViewTreeObserver.OnGlobalLayoutListener listener) {
ViewTreeObserver vto = view.getViewTreeObserver();
if (vto.isAlive()) {
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ViewTreeObserver vto = view.getViewTreeObserver();
if (vto.isAlive()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
vto.removeOnGlobalLayoutListener(this);
} else {
//noinspection deprecation
vto.removeGlobalOnLayoutListener(this);
}
listener.onGlobalLayout();
}
}
});
} else {
view.post(new Runnable() {
@Override
public void run() {
listener.onGlobalLayout();
}
});
}
}
** Old answer **
Strange but even if
view.getViewTreeObserver().isAlive() is true, then next call to view.getViewTreeObserver() may again produce the same exception. So, I surrounded a code with try-catch. Possibly you may skip all this and retain only view.post(...) block.
if (view.getViewTreeObserver().isAlive()) {
try {
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (view.getViewTreeObserver().isAlive()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
yourCode();
}
});
} catch (IllegalStateException e) {
e.printStackTrace();
// The same as below branch.
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
view.post(new Runnable() {
@Override
public void run() {
yourCode();
}
});
}
});
}
} else {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// Try to wait until the view is ready.
view.post(new Runnable() {
@Override
public void run() {
yourCode();
}
});
}
});
}
Probably view.post(...) is enough, but I called it from background thread, so if you do the same, better should invoke it from runOnUiThread(new Runnable() ....