9

Edited to add more details: (originally asked nearly two months ago...still haven't found a solution)

I have an activity with a somewhat complicated view. Not complicated in a technical sense...there's just a lot going on. All activities in this particular app are set to FullScreen NoTitleBar, and they're all set to Landscape orientation. I noticed early on in development when the app is hidden and then resumes, there was an infrequent tendency for the layout to slide down vertically as if to make room for the titlebar and statusbar.

Later on in development, the app now calls out to various external intents. I notice now that there is more of a tendency to make this same shift when resuming from an externally handled fired intent (such as creating a "chooser" intent or picking an image). I am able to reproduce it inconsistently using the exact same steps...sometimes it happens sometimes it doesn't. It seems as if there's a race condition in between various phases of measuring and laying out. I assume that one of these steps that the system is doing for me is checking for fullscreen and notitlebar, and making the necessary shift. This is probably happening late in some cases.

I put a bunch of logging, and calls to invalidate(), requestLayout(), etc trying to maybe catch the race condition, but the problem seems external to my layouts. The top() and bottom() values of my root layout are always 0 and the height of my screen, respectively, even when I'm logging this while the issue is occurring.

Is there some other method of the Window, WindowManager or any other system view-related object that I can force a full remeasure, redraw, re-check for current theme/style flags?

Rich
  • 36,270
  • 31
  • 115
  • 154

8 Answers8

9

i had exactly the same problem and also tried several aproches (as the ones mentioned above). None of them worked. However i found the following workaround:

 protected void onResume() {
   super.onResume();
   handler.postDelayed(new Runnable() {
      public void run() {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
      }
   }, 1000);    
 }

the view will do a short flicker in this procedure, but at least it doensn't stay croped. A clean solution still needs to be found. However this supports your thesis that there is some kind of timing or race problem.

r-hold
  • 941
  • 8
  • 30
  • So, in your case, does it also happen some times and not others? In the case where the issue doesn't arise (window is properly full screen when resumed), does this also cause a flicker? Or, is it just when the issue occurs and this situation fixes it? What sucks is that there's no way to detect the occurrence at runtime and maybe execute this code conditionally. I'll test this in my app and let you know if it works. Thanks! – Rich Mar 21 '11 at 17:29
  • @Rich: it occures in the emulator very reproducable (almost always) on devices it appears less frequently (depending on the device i think). Flicker/jumping just when the issue occurs. (I have regular flicker on one screen but i think its a different problem) – r-hold Mar 22 '11 at 11:09
  • Yep...this seems to be the best fix. Thanks again. – Rich Mar 29 '11 at 10:33
  • Any chance we could file this as a bug? I have the same issue, going to try this solution, but it's clearly a bug in Android. – Peterdk Apr 30 '11 at 09:56
  • Hi, i also tried above method but didnt work. anybody have the solution for this – Vishwanath.M Sep 17 '12 at 12:06
2

In my case this behavior was triggered by resume from lock screen. No idea why but after adding empty overloaded function it was fixed (but I tested it only on my HTC Wilfire). It may be a different bug thou.

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    /* Workaround a probable Android bug with fullscreen activities:
     * on resume status bar hides and black margin stays, 
     * reproducible half of the time when coming back from lock screen 
     * (tested on HTC Wildfire)
     * No idea why but this empty overload method fixed it.
     */
}
Paweł Prażak
  • 3,091
  • 1
  • 27
  • 42
  • Did you try on any other devices? FWIW, the accepted answer above was tested on a ton of different devices (both phone and tablet) and worked for me. Might not be the same issue, but probably related. – Rich Dec 21 '11 at 00:17
  • No I din't have the opportunity to test it on other device, but I hope it'll work as well ;) I've just figured it out yesterday. – Paweł Prażak Dec 21 '11 at 15:55
  • 1
    This solve my full screen problem after dialog dismissed... (what a 10 years question) – Nurkartiko Jul 07 '21 at 10:32
  • Looks like some things in Android never change ;) – Paweł Prażak Jul 07 '21 at 12:52
0

I have found a Solution to this:

    @Override
    protected void onResume() {
        Log.e("", "onResume");
        super.onResume();

        //this is a simple Splash with "Game paused" Text inside! in my main.xml
        final LinearLayout gamePause_text = (LinearLayout) findViewById(R.id.gamePause_text);
        OnGlobalLayoutListener asdf = new OnGlobalLayoutListener(){
            public void onGlobalLayout() {
                Log.e("", "onGlobalLayout");
                getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                                     WindowManager.LayoutParams.FLAG_FULLSCREEN);
                gameSurface.onResume(); //OpenGL Surface onResume();
                gamePause_text.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        };
        gamePause_text.getViewTreeObserver().addOnGlobalLayoutListener(asdf);
    }
tialawllol
  • 35
  • 6
0

I Fixed it by setting the theme for application rather than for individual activities.

<application
        android:icon="@drawable/icon"
        android:installLocation="auto"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >

This worked for me. This problem occurs if the next Activity we launch isnt a Full screen Activity and current Activity is a Full screen Activity.

0

I'm not sure if it'll work, but you might want to try this in that method:

this.getWindow().getDecorView().invalidate();

If that doesn't work on it's own, try adding to the onDraw(Canvas) method the instructions necessary to remove the title bar and do similar adjustments your activity might be doing at startup.

Hope that helps.

Luis Miguel Serrano
  • 5,029
  • 2
  • 41
  • 41
0

Hey Rich, I had the exact same problem. I fixed it by setting these options in the manifest XML (it seems the API interface is a little buggy). Details here: http://thedevelopersinfo.wordpress.com/2009/10/21/making-an-fullscreen-activity/

opticron

opticron
  • 9
  • 1
0

Have you set FullScreen NoTitleBar in your manifest or in code? If you use code, it may be that it is getting rendered before your code kicks in?

<application android:label="@string/app_name" android:icon="@drawable/icon" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

I understand that you can set themes on individual activities in an application. Do you? and do they conflict with your application settings?

FrinkTheBrave
  • 3,894
  • 10
  • 46
  • 55
  • I believe I've tried just about every combination of this. I can maybe do it again more meticulously to double check, but I tried in code, in the manifest, both, app level only, activitly level only, and both. I guess I'll write up a matrix of all possible combinations and test one by one, but my current thinking is that it's a race condition that needs a more hacky solution (hence the 250 pt bounty). – Rich Feb 01 '11 at 13:53
0

Have you tried this in onResume()?

this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                WindowManager.LayoutParams.FLAG_FULLSCREEN );
gnclmorais
  • 4,897
  • 5
  • 30
  • 41
  • I put that in onResume, onPostResume, onWindowConfigurationChanged, etc...you name it. Great suggestion, but it's something weirder than that. It happens at weird times and it corrects itself when I show/hide certain views or when a dialog pops up. I wish there was a callback that happens after all drawing is complete. I think that's what I'm looking for, but not sure if the Activity class exposes it. – Rich Feb 01 '11 at 15:00
  • That's really weird... If you find an answer, please post it here, I'll love to read it. – gnclmorais Feb 01 '11 at 15:20
  • There's no callback after drawing is complete, but I feel that you'd prefer a callback after all layout is complete; it's the layout phase that decides the positions of things, not the drawing phase. Use [`View.getViewTreeObserver()`](http://developer.android.com/reference/android/view/View.html#getViewTreeObserver%28%29) and [`OnPreDrawListener`](http://developer.android.com/reference/android/view/ViewTreeObserver.OnPreDrawListener.html). Don't know how much that will really help you, though, since forcing layout doesn't seem to work for you. – Neil Traft Feb 02 '11 at 19:16