I have a layout which includes a GLSurfaceView which takes up the whole screen. At the bottom of the screen, I have a semi-transparent toolbar (LinearLayout) which overlays the GLSurfaceView.
Also, my app is full screen (android:theme="@android:style/Theme.NoTitleBar.Fullscreen).
Usually, everything is fine, but starting with ICS, whenever the user comes back to the app (returning from onPause), the OS plays a quick animation where the app starts with the Android status bar showing at the top and the app screen pushed down. Then the status bar disappears and the app’s screen moves up by that much to get to its normal full screen position.
When this animation completes, the GLSurfaceView ends up overlaying the top half of the toolbar, with the toolbar overlaying the bottom half of the GLSurfaceView. It looks like the part of the toolbar showing at the bottom is exactly the size of the Android status bar.
Of course, I would like the toolbar to completely show and overlay the GLSurfaceView, which is what happens when the app is started all the way from onCreate.
Anybody has an idea about what causes this problem and how to fix it?
I found one workaround, but it is far from optimal.
I can get the toolbar to show correctly by posting invalidate() to the toolbar some time after onResume() is called. But if the invalidate() is called too quickly, the problem does not get fixed.
Here is the code for the workaround where invalidate() is called 5 seconds after onResume(), causing the toolbar to show correctly 5 seconds after the app restarts.
@Override
protected void onResume() {
super.onResume();
mGLSurfaceView.onResume();
// Test to try to fix half hidden toolbar problem
View toolBar = findViewById(R.id.menu_bar);
toolBar.postDelayed(new Runnable() {
@Override
public void run() {
View toolBar = findViewById(R.id.menu_bar);
toolBar.invalidate();
}
}, 5000);
}
Edit:
The above code does not cause the toolbar to show correctly. I took out a line setting text in a debug TextView in the code above, and it turns out that the toolbar does not show up if I don’t update that totally unrelated TextView!
I found another way to make the poor workaround above work by first removing the toolbar when onResume is called and bringing it back a while later. See the code below:
Please note that using View.INVISIBLE instead of View.GONE will not make the toolbar appear after the delay.
@Override
protected void onResume() {
super.onResume();
mGLSurfaceView.onResume();
// Test to try to fix half hidden toolbar problem
View toolBar = findViewById(R.id.menu_bar);
toolBar.setVisibility(View.GONE);
toolBar.postDelayed(new Runnable() {
@Override
public void run() {
View toolBar = findViewById(R.id.menu_bar);
toolBar.setVisibility(View.VISIBLE);
//mDebugText.setText("Menu bar to front.\n" + mDebugText.getText());
}
}, 5000);
}
I found more details about this problem and a better workaround, so here is the new info.
First, I discovered that the problem only happened when I was showing ads using Samsung’s
AdHubViewclass, which is derived fromRelativeLayout, so the problem might or might not be related toRelativeLayout.This ad view is included in the same top
FrameLayoutwhich also includes theGLSurfaceViewand the toolbar (LinearLayout). This topFrameLayoutis not explicitely declared since I used<merge >as the top element of my layout.Now about the better workaround, what I did is hide the
AdHubViewinonPauseand show it again inonWindowFocusChanged. I also tried showing it again inonResumebut that didn’t work in the case where the screen was turned off and I had to unlock the screen to return to the app.Here are some code samples:
With this workaround, I don’t need to wait before forcing the toolbar to the top anymore, as I was doing in my previous workaround, so the user never notices anything weird.