How to hide navigation bar permanently in android activity? - android

I want to hide navigation bar permanently in my activity(not whole system ui).
now i'm using this piece of code
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
It hides the bar but when user touches the screen it showing again. is there any way to hide it permanently until activity onStop();

Snippets:
FullScreenFragment.java
HideNavigationBarComponent.java
This is for Android 4.4+
Try out immersive mode https://developer.android.com/training/system-ui/immersive.html
Fast snippet (for an Activity class):
private int currentApiVersion;
#Override
#SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
currentApiVersion = android.os.Build.VERSION.SDK_INT;
final int flags = 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;
// This work only for android 4.4+
if(currentApiVersion >= Build.VERSION_CODES.KITKAT)
{
getWindow().getDecorView().setSystemUiVisibility(flags);
// Code below is to handle presses of Volume up or Volume down.
// Without this, after pressing volume buttons, the navigation bar will
// show up and won't hide
final View decorView = getWindow().getDecorView();
decorView
.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
{
#Override
public void onSystemUiVisibilityChange(int visibility)
{
if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
{
decorView.setSystemUiVisibility(flags);
}
}
});
}
}
#SuppressLint("NewApi")
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if(currentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus)
{
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);
}
}
If you have problems when you press Volume up or Volume down that your navigation bar show. I added code in onCreate see setOnSystemUiVisibilityChangeListener
Here is another related question:
Immersive mode navigation becomes sticky after volume press or minimise-restore

Do this.
public void FullScreencall() {
if(Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if(Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
}
}
This works 100% and you can do same for lower API versions, even if it's a late answer I hope it will helps someone else.
If you want this to be permanent, just call FullScreencall() inside your onResume() method.

For people looking at a simpler solution, I think you can just have this one line of code in
onStart()
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
It's called Immersive mode. You may look at the official documentation for other possibilities.

The other answers mostly use the flags for setSystemUiVisibility() method in View. However, this API is deprecated since Android 11. Check my article about modifying the system UI visibility for more information. The article also explains how to handle the cutouts properly or how to listen to the visibility changes.
Here are code snippets for showing / hiding system bars with the new API as well as the deprecated one for backward compatibility:
/**
* Hides the system bars and makes the Activity "fullscreen". If this should be the default
* state it should be called from [Activity.onWindowFocusChanged] if hasFocus is true.
* It is also recommended to take care of cutout areas. The default behavior is that the app shows
* in the cutout area in portrait mode if not in fullscreen mode. This can cause "jumping" if the
* user swipes a system bar to show it. It is recommended to set [WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER],
* call [showBelowCutout] from [Activity.onCreate]
* (see [Android Developers article about cutouts](https://developer.android.com/guide/topics/display-cutout#never_render_content_in_the_display_cutout_area)).
* #see showSystemUI
* #see addSystemUIVisibilityListener
*/
fun Activity.hideSystemUI() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.insetsController?.let {
// Default behavior is that if navigation bar is hidden, the system will "steal" touches
// and show it again upon user's touch. We just want the user to be able to show the
// navigation bar by swipe, touches are handled by custom code -> change system bar behavior.
// Alternative to deprecated SYSTEM_UI_FLAG_IMMERSIVE.
it.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// make navigation bar translucent (alternative to deprecated
// WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
// - do this already in hideSystemUI() so that the bar
// is translucent if user swipes it up
window.navigationBarColor = getColor(R.color.internal_black_semitransparent_light)
// Finally, hide the system bars, alternative to View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// and SYSTEM_UI_FLAG_FULLSCREEN.
it.hide(WindowInsets.Type.systemBars())
}
} else {
// 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
#Suppress("DEPRECATION")
window.decorView.systemUiVisibility = (
// Do not let system steal touches for showing the navigation bar
View.SYSTEM_UI_FLAG_IMMERSIVE
// Hide the nav bar and status bar
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
// Keep the app content behind the bars even if user swipes them up
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
// make navbar translucent - do this already in hideSystemUI() so that the bar
// is translucent if user swipes it up
#Suppress("DEPRECATION")
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
}
/**
* Shows the system bars and returns back from fullscreen.
* #see hideSystemUI
* #see addSystemUIVisibilityListener
*/
fun Activity.showSystemUI() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// show app content in fullscreen, i. e. behind the bars when they are shown (alternative to
// deprecated View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
window.setDecorFitsSystemWindows(false)
// finally, show the system bars
window.insetsController?.show(WindowInsets.Type.systemBars())
} else {
// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
#Suppress("DEPRECATION")
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
}

Try this for all android version including Android 30(R).
For more check this class: https://github.com/fiftyonemoon/Rapid/blob/main/rapid/src/main/java/com/fom/rapid/app/UI.java
Show/Hide all system bars:
public void hideSystemUI(Window window) { //pass getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.getInsetsController().hide(WindowInsets.Type.systemBars());
} else {
View decorView = window.getDecorView();
int uiVisibility = decorView.getSystemUiVisibility();
uiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
uiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN;
uiVisibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE;
uiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
decorView.setSystemUiVisibility(uiVisibility);
}
}
public void showSystemUI(Window window) { //pass getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.getInsetsController().show(WindowInsets.Type.systemBars());
} else {
View decorView = window.getDecorView();
int uiVisibility = decorView.getSystemUiVisibility();
uiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
uiVisibility &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
uiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE;
uiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
decorView.setSystemUiVisibility(uiVisibility);
}
}

Use:-
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
In Tablets running Android 4+, it is not possible to hide the System / Navigation Bar.
From documentation :
The SYSTEM_UI_FLAG_HIDE_NAVIGATION is a new flag that requests the
navigation bar hide completely. Be aware that this works only for the
navigation bar used by some handsets (it does not hide the system bar
on tablets).

According to Android Developer site
I think you cant(as far as i know) hide navigation bar permanently..
However you can do one trick. Its a trick mind you.
Just when the navigation bar shows up when user touches the screen. Immediately hide it again.
Its fun.
Check this.
void setNavVisibility(boolean visible) {
int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_LAYOUT_STABLE;
if (!visible) {
newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
| SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
// If we are now visible, schedule a timer for us to go invisible.
if (visible) {
Handler h = getHandler();
if (h != null) {
h.removeCallbacks(mNavHider);
if (!mMenusOpen && !mPaused) {
// If the menus are open or play is paused, we will not auto-hide.
h.postDelayed(mNavHider, 1500);
}
}
}
// Set the new desired visibility.
setSystemUiVisibility(newVis);
mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
mPlayButton.setVisibility(visible ? VISIBLE : INVISIBLE);
mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
}
See this for more information on this ..
Hide System Bar in Tablets

It's my solution:
First, define boolean that indicate if navigation bar is visible or not.
boolean navigationBarVisibility = true //because it's visible when activity is created
Second create method that hide navigation bar.
private void setNavigationBarVisibility(boolean visibility){
if(visibility){
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
navigationBarVisibility = false;
}
else
navigationBarVisibility = true;
}
By default, if you click to activity after hide navigation bar, navigation bar will be visible. So we got it's state if it visible we will hide it.
Now set OnClickListener to your view. I use a surfaceview so for me:
playerSurface.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setNavigationBarVisibility(navigationBarVisibility);
}
});
Also, we must call this method when activity is launched. Because we want hide it at the beginning.
setNavigationBarVisibility(navigationBarVisibility);

I think the blow code will help you, and add those code before setContentView()
getWindow().setFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
Add those code behind setContentView()
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);

Its a security issue:
https://stackoverflow.com/a/12605313/1303691
therefore its not possible to hide the Navigation on a tablet permanently with one single call at the beginning of the view creation. It will be hidden, but it will pop up when touching the Screen. So just the second touch to your screen can cause a onClickEvent on your layout. Therefore you need to intercept this call, but i haven't managed it yet, i will update my answer when i found it out. Or do you now the answer already?

Try this:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);

I think this code will resolve your issue. Copy and paste this code on your MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
hideNavigationBar();
}
}
});
}
private void hideNavigationBar() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
It will works on Android-10. I hope it will helps.

You can hide Navigator Bar using this:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
View decorView = getWindow().getDecorView();
if(hasFocus){
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
);
}
}
This way you can hide Navigation Buttons without hiding Status bar

Here is the hide and show system UI for android 11 and Below. But below from Android its deprecated.
private fun hideSystemUI() {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowInsetsControllerCompat(window, drawerLayoutID).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
private fun showSystemUI() {
WindowCompat.setDecorFitsSystemWindows(window, true)
WindowInsetsControllerCompat(
window,
drawerLayoutID
).show(WindowInsetsCompat.Type.systemBars())
}
private fun hideSystemUIBeloR() {
val decorView: View = window.decorView
val uiOptions = decorView.systemUiVisibility
var newUiOptions = uiOptions
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_LOW_PROFILE
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_FULLSCREEN
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE
newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
decorView.systemUiVisibility = newUiOptions
}
private fun showSystemUIBelowR() {
val decorView: View = window.decorView
val uiOptions = decorView.systemUiVisibility
var newUiOptions = uiOptions
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_LOW_PROFILE.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_FULLSCREEN.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_HIDE_NAVIGATION.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_IMMERSIVE.inv()
newUiOptions = newUiOptions and View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY.inv()
decorView.systemUiVisibility = newUiOptions
}

Related

How to hide navigation bar again after user scrolled it manually up?

In a certain activity in my app I am hiding the navigation bar since that activity is full screen. To hide the navigation bar I am using the following code:
private void hideSystemUI() {
// 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
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN
);
}
This code works fine until the user swipes up the navigation bar. It then stays there. What I want is that it hides again after 2 seconds or so. Is there a way to achieve this?
I appreciate any help!
You can Use this code:
private FullScreenListener fullScreenListener = new FullScreenListener();
private void initUiFlags() {
int flags = View.SYSTEM_UI_FLAG_VISIBLE;
flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(flags);
decorView.setOnSystemUiVisibilityChangeListener(fullScreenListener);
}

Fullscreen fragment with transparent status bar (programmatically)

I have an app which is based on single activity and multiple fragments and some fragments needs to show into fullscreen when enters fragment and exit from fullscreen when exit. I am currently using flags to show fullscreen in Android Kitkat but its not optimal way i think. I also read ImmersiveMode but it's not working in lower Android version. Currently i am using these methods for fullscreen enter and exit.
//This method not showing transparent status bar also navigation bar and not showing system icons either
public static void setFullscreen(Activity activity) {
if (Build.VERSION.SDK_INT > 10) {
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN;
boolean isImmersiveAvailable = android.os.Build.VERSION.SDK_INT >= 19;
if (isImmersiveAvailable) {
flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
activity.getWindow().getDecorView().setSystemUiVisibility(flags);
} else {
activity.getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
public static void exitFullscreen(Activity activity) {
if (Build.VERSION.SDK_INT > 10) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
} else {
activity.getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
}
public static void ShowHideFullscreen(boolean isFullscreen,Context cntx){
int newUiOptions = 0;
if (isFullscreen){
// BEGIN_INCLUDE (get_current_ui_flags)
// The UI options currently enabled are represented by a bitfield.
// getSystemUiVisibility() gives us that bitfield.
int uiOptions = ((Activity)cntx).getWindow().getDecorView().getSystemUiVisibility();
newUiOptions = uiOptions;
// END_INCLUDE (get_current_ui_flags)
// BEGIN_INCLUDE (toggle_ui_flags)
boolean isImmersiveModeEnabled =
((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
if (isImmersiveModeEnabled) {
Log.d(TAG, "Turning immersive mode mode off. ");
} else {
Log.d(TAG, "Turning immersive mode mode on.");
}
// Navigation bar hiding: Backwards compatible to ICS.
if (Build.VERSION.SDK_INT >= 14) {
newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
// Status bar hiding: Backwards compatible to Jellybean
if (Build.VERSION.SDK_INT >= 16) {
newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
}
// Immersive mode: Backward compatible to KitKat.
// Note that this flag doesn't do anything by itself, it only augments the behavior
// of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of this sample
// all three flags are being toggled together.
// Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
// Sticky immersive mode differs in that it makes the navigation and status bars
// semi-transparent, and the UI flag does not get cleared when the user interacts with
// the screen.
if (Build.VERSION.SDK_INT >= 18) {
newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
((Activity)cntx).getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
}else {
((Activity)cntx).getWindow().clearFlags(newUiOptions);
}
}
These are method we use to enter or exit from fullscreen in fragment with hiding action bar. We use these to entered in fullscreen on onCreate and exit on onPause but sometimes it fails to show desired result.
We need to know what are the optimal way to show fullscreen fragment on lower API too(KITKAT) and also which are the best way to hide toolbar when showing fullscreen because our code ((AppCompatActivity)Objects.requireNonNull(getActivity())).getSupportActionBar().hide();
throws nullpointerexception sometimes.
Our issue:
Show fullscreen fragment with transparent status bar and drawing system icon over fullscreen fragment and transparent navigation bar.
Hiding and showing toolbar with method which safe to call without getting NullpointerExepection
We can target android Kitkat as lowest android version.
Fragment Fullscreen example with system icons and transparent navigation bar.
Update: I set IMMERSIVE mode on my fragment onResume and reset it back at onStop by these method.
private void hideSystemUI() {
// 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
View decorView = getActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar().hide();
}
// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
View decorView = getActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar().show();
}
It shows my fragment in fullscreen with status bar hidden (that's not what i want) and my fragments belong to Navigation Drawer. when i press back button from fullscreen fragment it shows my status bar over toolbar in previous fragment.
I solved this issue by creating a method which clears desired flags at onStop and add flags at onResume
#Override
public void onResume() {
super.onResume();
App_Functions.transparentStatusBar(getActivity(),true,false);
}
#Override
public void onStop() {
super.onStop();
App_Functions.transparentStatusBar(getActivity(),false,false);
}
if i want to show transparent statusbar but navigation bar should be same then i use true in first parameters of method and for clearing that flag just use false. Same way i am using true for complete fullscreen and false for clearing fullscreen flags
public static void transparentStatusBar(Activity activity, boolean isTransparent, boolean fullscreen) {
if (isTransparent){
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
((AppCompatActivity) Objects.requireNonNull(activity)).getSupportActionBar().hide();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
defaultStatusBarColor = activity.getWindow().getStatusBarColor();
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// FOR TRANSPARENT NAVIGATION BAR
//activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
Log.d(TAG,"Setting Color Transparent "+Color.TRANSPARENT+ " Default Color "+defaultStatusBarColor);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.d(TAG,"Setting Color Trans "+Color.TRANSPARENT);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}else {
if (fullscreen){
View decorView = activity.getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}else {
((AppCompatActivity) Objects.requireNonNull(activity)).getSupportActionBar().show();
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity.getWindow().setStatusBarColor(defaultStatusBarColor);
}else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}
}
}
Please feel free to recommend better way to use this method across all platform.
How to handle the toolbar from fragment?
Where to put the toolbar is highly opinionated. But I recommend you to put the toolbar in each fragment xml file rather than keeping one toolbar for the whole application in the Activity xml file. See this sample app by Google, they are also placing the AppbarLayout and toolbar per Fragment rather than keeping it in the activity layout file.
So if you place the toolbar with in the fragment, you can easily hide/show it from the fragment without the fear of getting null pointer exceptions.
So your activity xml file will simply contain the NavHost Fragment only. So the whole screen will be managed by the currently visible Fragment :)
How to get the transparent statusbar for older API levels?
Devices below kitkat would not support transparent statusbar feature. Kitkat supports transluent statusbar, not transparent. So you can use transparent statusbar for API level lollipop or above. If the device version is below lollipop, ignore it as the platform does not support the feature. So rest of my answer assumes you want to achieve transparent status bar when the device version is lollipop or above.
Well then, How to get transparent status-bar for lollipop and above for selected fragments?
We need to create a custom NavHostFragment. This is required because, during fragment transitions, multiple fragment's view hierarchies can be added at the same time. If one consumes window insets, the other might not be laid out properly. To workaround that, we need to make sure we dispatch the insets to all children, regardless of how they are consumed.
class DispatchInsetsNavHostFragment : NavHostFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
view.setOnApplyWindowInsetsListener { v, insets ->
(v as? ViewGroup)?.forEach { child ->
child.dispatchApplyWindowInsets(insets)
}
insets
}
}
}
}
Wrap your nav host fragment with a Framelayout as shown below and put android:fitsSystemWindows="true"
<FrameLayout
android:id="#+id/navHostContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<fragment
android:id="#+id/navHostFragment"
android:name="com.yourdomain.app.DispatchInsetsNavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/main" />
</FrameLayout>
Set the following flags to the navHostContainer which we defined above, from your MainActivity class onCreate method after setContentView.
val navHostContainer: FrameLayout = findViewById(R.id.navHostContainer)
navHostContainer.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Make the content ViewGroup ignore insets so that it does not use the default padding
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
navHostContainer.setOnApplyWindowInsetsListener(NoopWindowInsetsListener)
}
Here is the NoopWindowInsetsListener
object NoopWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
return insets
}
}
Thats all, from now on, your fragments has the complete ownership to the statusbar area. Your views will be drawn behind the transparent status bar. For some fragments, you may not want the statusbar to overlap your content, for those fragments, simply put android:fitsSystemWindows="true" to your root layout in the Fragment xml file.
How to set custom statusbar color for some Fragments?
Use the app:statusBarBackground attribute of CoordinatorLayout with android:fitsSystemWindows="true"
That's all. Happy coding :)
1- in style xml file change AppTheme parent to NoActionBar:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
2- use this method in your activity for transparent statusBar
private void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(ContextCompat.getColor(this, android.R.color.transparent));
}
}
3- match_parent frameLayout tag in your activity_main(xml) for full screen the fragment

Immersive Mode showing blank space

I'm trying to implement a fullscreen mode, but for Android 4.4 and up, it shows a blank space there:
BEFORE immersive mode(fullscreen)
and AFTER the toggleFullScreen(false);
as you can see, its doesn't remove it. Here's the code that I'm using to toggle it:
public void toggleFullscreen(boolean fs) {
if (Build.VERSION.SDK_INT >= 11) {
// The UI options currently enabled are represented by a bitfield.
// getSystemUiVisibility() gives us that bitfield.
int uiOptions = this.getWindow().getDecorView().getSystemUiVisibility();
int newUiOptions = uiOptions;
boolean isImmersiveModeEnabled =
((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
if (isImmersiveModeEnabled) {
Log.i(getPackageName(), "Turning immersive mode mode off. ");
} else {
Log.i(getPackageName(), "Turning immersive mode mode on.");
}
// Navigation bar hiding: Backwards compatible to ICS.
if (Build.VERSION.SDK_INT >= 14) {
newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
// Status bar hiding: Backwards compatible to Jellybean
if (Build.VERSION.SDK_INT >= 16) {
newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
}
// Immersive mode: Backward compatible to KitKat.
// Note that this flag doesn't do anything by itself, it only augments the behavior
// of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of this sample
// all three flags are being toggled together.
// Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
// Sticky immersive mode differs in that it makes the navigation and status bars
// semi-transparent, and the UI flag does not get cleared when the user interacts with
// the screen.
if (Build.VERSION.SDK_INT >= 18) {
newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
} else {
// for android pre 11
WindowManager.LayoutParams attrs = getWindow().getAttributes();
if (fs) {
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
} else {
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
}
this.getWindow().setAttributes(attrs);
}
try {
// hide actionbar
if
(this instanceof AppCompatActivity) {
if (fs) getSupportActionBar().hide();
else getSupportActionBar().show();
} else if
(Build.VERSION.SDK_INT >= 11) {
if (fs) getActionBar().hide();
else getActionBar().show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Please check that you don't have android:fitsSystemWindows="true" in your layout.
At least it solved my case - I had fitsSystemWindows on FrameLayout.
I'm new here so I can't comment, but wanted to add something that got me so frustrated me about the above solution. I kept checking my activities and its fragments for android:fitsSystemWindows="true" and it was definitely not there, yet I kept having a gap at the bottom! I was going nuts! It couldn't be this hard to fix this simple thing!
Turns out it also showed up in the Navigation Drawer I added...so be sure to check all your XML!
Try this:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var viewParent = view
while (viewParent is View) {
viewParent.fitsSystemWindows = false
viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
viewParent = viewParent.parent as View?
}
}
What does this do? DialogFragment#onActivityCreated() calls Dialog#setContentView(), which wraps the Dialog's view in a private 'wrapInBottomSheet'. In order to set the proper flags of those wrapper views, we want to set the flags after they are wrapped, e.g. after super.onActivityCreated()
Also watch this talk for info on fitsSystemWindows and window insets.
Just change the android:fitsSystemWindows="true" to android:fitsSystemWindows="false" in your layout file.
You need to add this flag to your view View.SYSTEM_UI_FLAG_LAYOUT_STABLE. Try it like this
// This snippet hides the system bars.
private void hideSystemUI() {
// Set the IMMERSIVE flag.
// Set the content to appear under the system bars so that the content
// doesn't resize when the system bars hide and show.
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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

Android: show/hide status bar/power bar

I am trying to create a button where I can hide or show the status bar on my tablet.
I've put in the onCreate
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
and in the buttons
show:
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
hide:
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
Any hints/tipps?
//edit
I've looked at this hint here: http://android.serverbox.ch/?p=306
and changed my code like this:
private void hideStatusBar() throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(new String[]{"su","-c","service call activity 79 s16 com.android.systemui"});
proc.waitFor();
}
private void showStatusBar() throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(new String[]{"am","startservice","-n","com.android.systemui/.SystemUIService"});
proc.waitFor();
}
So if I click on my buttons an the methods are called I can see that something is happening because the app is waiting some seconds.
I also looked into LockCat and see that something is happening.
show: http://pastebin.com/CidTRSTi
hide: http://pastebin.com/iPS6Kgbp
Do you have the fullscreen theme set in the manifest?
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
I don't think you'll be able to go fullscreen without this.
I would use the following to add and remove the fullscreen flag:
// Hide status bar
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Show status bar
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
For Some People, Showing status bar by clearing FLAG_FULLSCREEN may not work,
Here is the solution that worked for me, (Documentation) (Flag Reference)
Hide Status Bar
// Hide Status Bar
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
else {
View decorView = getWindow().getDecorView();
// Hide Status Bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
Show Status Bar
if (Build.VERSION.SDK_INT < 16) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
else {
View decorView = getWindow().getDecorView();
// Show Status Bar.
int uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
decorView.setSystemUiVisibility(uiOptions);
}
used for kolin in android
for hide status bar in kolin no need to used semicolon(;) at the end of the line
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
in android using java language for hid status bar
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
I know its a very old question, but just in case anyone lands here looking for the newest supported way to hide status bar on the go programmatically, you can do it as follows:
window.insetsController?.hide(WindowInsets.Type.statusBars())
and to show it again:
window.insetsController?.show(WindowInsets.Type.statusBars())
I've tried so many things.
Finally, It is the most suitable code to hide and show full screen mode.
private fun hideSystemUi() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(true)
} else {
// hide status bar
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_IMMERSIVE or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
}
}
private fun showSystemUi() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false)
} else {
// Show status bar
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.decorView.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_STABLE
}
}
It Implemented it in this app : Android Breakdown.
Go to Videos(Bottom Bar) > Play Any Video > Toggle Fullscreen
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//hide status bar
requestWindowFeature( Window.FEATURE_NO_TITLE );
getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN );
setContentView(R.layout.activity_main);
}
For Kotlin users
TO SHOW
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
TO HIDE
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
with this method, using SYSTEM_UI_FLAG_IMMERSIVE_STICKY the full screen come back with one tap without any implementation. Just copy past this method below and call it where you want in your activity.
More details here
private void hideSystemUI() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
Reference - https://developer.android.com/training/system-ui/immersive.html
// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
fun Activity.setStatusBarVisibility(isVisible: Boolean) {
//see details https://developer.android.com/training/system-ui/immersive
if (isVisible) {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
} else {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
}

Hide status bar while having Media controller on android

i am using this method to hide status bar :
public static void hideStatusBar(Activity activity) {
if (Build.VERSION.SDK_INT < 16) {
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
View decorView = activity.getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
this works fine but when i start video i have notice the status bar is visible again , after some test on my code i have realized that the status bar i visible after i add the MediaController .
how can i keep my full screen and still using MediaController ?
this is how i add the MediaController
mMediaController = new MediaController(getContext());
mMediaController.setAnchorView(this);
setMediaController(mMediaController);
use:
<application
...
android:theme="#android:style/Theme.Holo.NoActionBar.Fullscreen" >
...
</application>
or
View decorView = getWindow().getDecorView();
// Hide the status bar.
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
// Remember that you should never show the action bar if the
// status bar is hidden, so hide that too if necessary.
ActionBar actionBar = getActionBar();
actionBar.hide();
and see this link:
http://developer.android.com/training/system-ui/status.html
and this link:
How to hide status bar in Android
Yes, the videoView can bring back the status bar. Not sure what the behind principle is. While you can resolve it by setting a setOnSystemUiVisibilityChangeListener, Something like:
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
}
});

Categories

Resources