I have a custom View to represent an ImageView with a parallax effect, adapted from the one found in the answer to this SO question: How to have a wider image scrolling in the background.
The View has a setBackgroundDrawable() method to set its background image that does some calculations to know the size that the bitmap should have in order to be wide enough to be scrolled with a parallax effect, if cropping is needed to keep the aspect ratio, etc.
I'm getting an "IllegalArgumentException: width and height must be > 0" in
(...)
int width = this.getWidth();
int height = this.getHeight();
Bitmap mCurrentBackground=Bitmap.createBitmap((int) (width*FACTOR), height, Config.ARGB_8888);
(...)
because getWidth() and getHeight() are returning zero.
I understand that this is happening because the View doesn't know its own size yet when I call the said function, for example, in an Activity's onCreate method. Same thing happens if I try to set the background in onStart or onResume...
I've managed to set the background if I call the function in onWindowFocusChanged(), but I still get the error sometimes (e.g. if I switch the screen orientation when an EditText is focused).
Is there a way to get around this? Any kind of callback or phase in the lifecycle where the whole View was created (like the onViewCreated from the Fragment class)? I can only call my custom View's setBackgroundDrawable after the View has been assigned a height and a width.
EDIT:
I have also tried adding a GlobalLayoutListener to the View's ViewTreeObserver:
ViewTreeObserver vto = parallaxBackground.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
...
parallaxBackground.setBackgroundDrawable(d1);
ViewTreeObserver obs = parallaxBackground.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
but it results in the same behavior I get from setting the background in the onWindowFocusChanged() method. I.e. the gedtWidth()/getHeight() return zero inside the listener's onGlobalLayout if I switch the phone's orientation when an EditText is selected.
EDIT 2:
It probably has something to do with the keyboard as I observed some behavior like the height being calculated taking the keyboard's existence into account.
Deleting:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
from my onGlobalLayout shown in the first EDIT seems to do the trick.