I have an app that I want to run in fullscreen. If i have a device with 4.4 KitKat it is easy to set the SYSTEM_UI_FLAG_IMMERSIVE to make the app go pure fullscreen.
However if i have a device with a lower API than 4.4. I have no idea how to make it fullscreen as if it was a KitKat with Immersive support.
I can set the Fullscreen, and hide navigation flags to make the app go fullscreen, but as soon as the screen is clicked, these flags are reset and will now show both navbar and statusbar.
Is there a solution where i can "simulate" the immersive mode on devices with JB and possibly ICS (not necesserily below).
I have a method hideSystemUI which runs when OnSystemUiVisibilityChangeListener triggers which look like this at the moment.
private void hideSystemUI() {
actionBar.hide();
isMenuVisible = false;
if (currentapiVersion >= android.os.Build.VERSION_CODES.KITKAT){
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
else{
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
}
What changes do I need to make to make the app go fullscreen and not showing navbar and statusbar on every click, but rather on slide from top or bottom.
This is as close as you're going to get:
if (Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
} else {
if (Build.VERSION.SDK_INT > 10) {
findViewById(android.R.id.content).setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
}
}
And don't support devices with an SDK less than 10. Those jokers need to get a modern android anyway.
I had faced the same situation and after some research i figured out it is not possible below 4.4 because of security issues, and so old APIs wont support hiding navigation bar the way you want.
Even though from API 4.1 your use of SYSTEM_UI_FLAG_LAYOUT_STABLE flag your layout won't resize and it will inflate behind navigation bar, but you need to make sure none of your important UI components are covered by it.
https://developer.android.com/training/system-ui/immersive.html
Hope this helps..:)
just copy past below code into value/style.xml.
<resources>
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
</style>
There are two method for immersive mode
To make it remain immersive do change thid line
View.SYSTEM_UI_FLAG_IMMERSIVE
By this line-
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
Related
I've successfully set the app in the immersive mode because I want to hide the status bar (on the top screen) and the navigation bar (on the bottom screen).
The problem is that when the activity changes the bottom bar automatically arise and immediately after go down and disappear.
I want to avoid this.
All activities have the style AppTheme.NoActionBar set in the manifest:
android:theme="#style/AppTheme.NoActionBar"
And in the OnCreate all have the following code:
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
GlobalFunctions.setFullscreen(getWindow().getDecorView());
}
});
Where this is the setFullscreen() function:
public static void setFullscreen(View decorView){
int ui_Options = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(ui_Options);
}
Should I set these attributes before the onCreate in the activity lifecycle? or there are other solutions? or I've implemented the immersive mode in the wrong way?
You don't need to set the global layout listener. Just invoke the setFullscreen function before super.onCreate()
Use this code in manifest activity tag
android:theme="#style/AppFullScreenTheme"
create this style in style.xml
<style name="AppFullScreenTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:fontFamily">#font/montserrat</item>
<item name="android:windowContentOverlay">#null</item>
</style>
else use this in your activity class
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
this worked for me.
I have added an splash screen on my flutter app (on Android side) like this:
Opening the values/styles.xml and adding the following:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="#android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<!--following 2 lines modified by me-->
<item name="android:windowBackground">#drawable/splash_screen</item>
<item name= "android:windowFullscreen">true</item>
</style>
</resources>
However, when I run the app in real device, the splash screen shows a weird behaviour:
I am not sure how many seconds the splash is shown but, for the example, let's say it lasts for 3 seconds, well, on the first 1 or 1.5 seconds, the bottom of the screen looks like this, showing the bottom software buttons:
After these 1 or 1.5 secs, the bottom bar goes away and the splash screen is shown as expected for another 1 or 1.5 secs, then the app starts.
How to fix this so that the splash covers the whole screen from the beginning?
In MainActivity.java
write this:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
I have a problem with SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR somehow not working, but SYSTEM_UI_FLAG_LIGHT_STATUS_BAR is working. I'm working with Android API 28 at the moment.
So whats happening? On API 23 and below I get translucent Status Bar and Navigation Bar as expected. Between API 23 and API API 26 I get transculent Navigation Bar and Light Mode Status bar as expected. But on API 27 and above I get the Light Mode Status Bar but not the Light Mode Navigation Bar. It just is the normal black one and nothing changes.
Here is my MainActivity with my code to enable Translucent or Light Mode Status Bar and Navigation Bar based on the Android API Level (Note my comments describe what works and what doesn't):
View decorView = getWindow().getDecorView();
Window win = getWindow();
//Setup Status Bar and Nav Bar white if supported
if(Build.VERSION.SDK_INT >= 27) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);// <- works not
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); // <- works
}
else if (Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT < 27) {
//this here works
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
win.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
} else {
//this here works
win.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
win.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
And this here is my style.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorWhite</item>
<item name="colorPrimaryDark">#color/colorWhite</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:textColorPrimary">#color/colorBlack</item>
<item name="android:fitsSystemWindows">true</item>
</style>
</resources>
Can you guys tell me what's missing? I use the exact same code for Navigation bar as I do for the Status Bar but only the Status Bar gets Light Mode. Thanks for every help
After hours of testing I figured it out! First you have to set your Navigation Bar to white in xml with target API above 26 in your style.xml:
<item name="android:navigationBarColor" tools:targetApi="27">#android:color/white</item>
After that you have to import this flag in your Main Activity:
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
And in your Code you have to set the flags all toghether like this:
if(Build.VERSION.SDK_INT >= 27) {
decorView.setSystemUiVisibility(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS |
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
And now if Im above API 26 I get Light Nav and Status Bar!
In your code NAVIGATION_BAR flag is getting override by STATUS_BAR Flag.
To add both the flag replace.
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
With
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
Update:
You can also specify the Color of the NavigationBar
getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.primary));
I'm currently working on something where I want the status and navigation bars to be transparent, with the content going behind them. Currently, I have the bars set to #android:color/transparent in styles.xml and am able to get the content behind the status bar with this code:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
However I am still struggling to get it behind the nav bar. Any help appreciated.
Thanks,
Josh
You need:
getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Check out the answer here:
Showing content behind status and navigation bar
Try to add these in your activity's style.xml:
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:fitsSystemWindows">true</item>
hope this can help.
An app that uses immersive mode leaves a black bar at the bottom of the screen when the app is returned to after waiting a while (activity is destroyed).
What is happening: (I have enabled the developer option: "Don't keep activities" to reproduce this).
First time launch of the app. Immersive mode works as expected.
Swipe up to reveal the 'immersive sticky' nav bar, and use the 'Home' button to leave the app. The background of the nav bar briefly shows a black background before the app closes.
Use the 'Recents' button, and select the app to resume it.
The app opens to briefly reveal the nav bar over a black bar. The system ui collapses into immersive mode but the black bar remains.
This bug also only appears on Lollipop, not KitKat.
I have stripped back the app to simply launching a dummy activity with no functionality apart from setting System UI flags:
public class DummyActivity extends FragmentActivity {
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
setSystemUiVisibility();
}
}
public void setSystemUiVisibility() {
if (getWindow() != null && getWindow().getDecorView() != null) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
}
EDIT:
After creating a new fresh project with only this Activity I have seen this issue reproduced when using an app theme extending "android:Theme.Holo"..., and fixed the issue in this sample project when I extend the Material theme instead:
Change
<style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">
</style>
to
<style name="AppTheme"parent="android:Theme.Material.Light.NoActionBar.Fullscreen">
</style>
Unfortunately this fix hasn't solved the issues in my main project, but it brings me closer to a solution and might help others with the same issue.
I was having the same problem. Here are a few updates I made which made it go away. Hopefully one of these works for you!
activity_main.xml
android:fitsSystemWindows="false"
style-v21
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowSharedElementsUseOverlay">false</item>
MainActivity.java
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_FULLSCREEN
);
For me it was a black bar at the top. Key thing was this in the activity style:
// Important to draw behind cutouts
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
Here is my code:
1- In Activity
private fun hideSystemUI() {
sysUIHidden = true
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Hide the nav bar and status bar
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // Hide nav bar
or View.SYSTEM_UI_FLAG_FULLSCREEN // Hide status bar
)
}
private fun showSystemUI() {
sysUIHidden = false
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION // layout Behind nav bar
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // layout Behind status bar
)
}
2- In root view of xml layout
android:fitsSystemWindows="false"
3- Style for the Full screen Activity:
<style name="FullscreenTheme" parent="AppTheme">
<item name="android:actionBarStyle">#style/FullscreenActionBarStyle</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#null</item>
<item name="metaButtonBarStyle">?android:attr/buttonBarStyle</item>
<item name="metaButtonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
<item name="android:statusBarColor">#50000000</item>
<item name="android:navigationBarColor">#50000000</item>
// Important to draw behind cutouts
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
<item name="android:background">#color/sysTransparent</item>
</style>
Using
<style name="AppTheme"parent="android:Theme.Material.Light.NoActionBar.Fullscreen"> </style>
does solved the problem, but it only work for api:21.
In order to make it works for all system. You can create a directory called style-v21 in res directory, and put that style.xml there. Android system is smart enough to pick which one to use for new or old phone.