Hide StatusBar for specific ContentPage

11,778

Solution 1

As far as I know, Xamarin doesn't provide this functionality through Xamarin.Forms classes. You will need to implement it in each platform specific project.

However, this should be fairly easy as you can use a DependencyService to handle this.

Here is a quick implementation...

App.cs

public App()
{
    var layout = new StackLayout
    {
        VerticalOptions = LayoutOptions.Center,
        Children =
        {
            new Label
            {
                XAlign = TextAlignment.Center,
                Text = "Welcome to Xamarin Forms!"
            }
        }
    };

    var button = new Button
    {
        Text = "Click Me"
    };
    button.Clicked += (object sender, EventArgs e) => 
        {
            if (_isHidden)
            {
                // show
                DependencyService.Get<IStatusBar>().ShowStatusBar();
            }
            else
            {
                // hide
                DependencyService.Get<IStatusBar>().HideStatusBar();
            }

            _isHidden = !_isHidden;
        };

    layout.Children.Add(button);

    // The root page of your application
    MainPage = new ContentPage
    {
        Content = layout
    };
}

IStatusBar.cs

public interface IStatusBar
{
    void HideStatusBar();
    void ShowStatusBar();
}

AndroidImplementation

[assembly: Xamarin.Forms.Dependency(typeof(StatusBarImplementation))]
namespace MyXamarinApp.Droid
{
    public class StatusBarImplementation : IStatusBar
    {
        public StatusBarImplementation()
        {
        }

        WindowManagerFlags _originalFlags;

        #region IStatusBar implementation

        public void HideStatusBar()
        {
            var activity = (Activity)Forms.Context;
            var attrs = activity.Window.Attributes;
            _originalFlags = attrs.Flags;
            attrs.Flags |= Android.Views.WindowManagerFlags.Fullscreen;
            activity.Window.Attributes = attrs;
        }

        public void ShowStatusBar()
        {
            var activity = (Activity)Forms.Context;
            var attrs = activity.Window.Attributes;
            attrs.Flags = _originalFlags;
            activity.Window.Attributes = attrs;
        }

        #endregion
    }
}

iOSImplementation

[assembly: Xamarin.Forms.Dependency(typeof(StatusBarImplementation))]
namespace MyXamarinApp.iOS
{
    public class StatusBarImplementation : IStatusBar
    {
        public StatusBarImplementation()
        {
        }

        #region IStatusBar implementation

        public void HideStatusBar()
        {
            UIApplication.SharedApplication.StatusBarHidden = true;
        }

        public void ShowStatusBar()
        {
            UIApplication.SharedApplication.StatusBarHidden = false;
        }

        #endregion
    }
}

The idea being that you call the DependencyService implementation to hide the status bar when you need it hidden on a specific ContentPage. You also may need to show it again after hiding(not really sure).

NOTE: For iOS, you need to update the Info.plist file to allow the application to change the status bar visibility.

Info.plist

Solution 2

You could use a PageRenderer for this. Here is an example:

public class NoStatusBarPageRenderer : PageRenderer
{
    public NoStatusBarPageRenderer()
    {
    }

    public override void ViewWillAppear(bool animated)
    {
        UIApplication.SharedApplication.SetStatusBarHidden(true, UIStatusBarAnimation.Fade);

        base.ViewWillAppear(animated);
    }

    public override void ViewDidDisappear(bool animated)
    {
        UIApplication.SharedApplication.SetStatusBarHidden(false, UIStatusBarAnimation.Fade);

        base.ViewDidDisappear(animated);
    }
}

Then, for each page that you want to have the status bar hidden, add an attribute to use this renderer on that page.

[assembly: ExportRenderer(typeof(MyContentPage), typeof(NoStatusBarPageRenderer))]
Share:
11,778
Rasmus Christensen
Author by

Rasmus Christensen

Professional Software Developer Located in Denmark. Works mainly on the .NET platform in C# with ASP.NET MVC and WPF. Always hacking on an idea

Updated on July 27, 2022

Comments

  • Rasmus Christensen
    Rasmus Christensen almost 2 years

    I'm creating an app where I want to hide the statusbar on a specific page. In my example it's a ContentPage. I found several samples where the info.plist is used to hide it, but I only want it for a specific page, is it possible? It's easy to hide the navigationbar with NavigationPage.SetHasNavigationBar, but statusbar seems a bit different.

  • Ryan Alford
    Ryan Alford about 8 years
    That would hide the status bar for all views in a Xamarin.Forms app(going by the Xamarin.Forms tag on the question), and only work on Android.
  • Rasmus Christensen
    Rasmus Christensen about 8 years
    The implementation for android would be public void Hide () { var activity = Forms.Context as Activity; activity.Window.ClearFlags (WindowManagerFlags.Fullscreen); } public void Show () { var activity = Forms.Context as Activity; activity.Window.AddFlags (WindowManagerFlags.Fullscreen); }
  • Ryan Alford
    Ryan Alford about 8 years
    @RasmusChristensen I would make sure that works on all versions of Android that you need to support. I originally tried that on Android 4.1.1 and it didn't work. That's why I went with the code above.
  • Rasmus Christensen
    Rasmus Christensen about 8 years
    You need the assembly attribute on the namespace level, not the class level. Just a minor detail. It works perfect
  • Rasmus Christensen
    Rasmus Christensen about 8 years
    Actually it seems that doing it during a pagerenderer is the faster compared to DependecyService. Maybe because it happens before appearing and disappering
  • Ryan Alford
    Ryan Alford about 8 years
    I removed the namespace all together for that purpose :)
  • Peter
    Peter over 7 years
    It doesn't work on Android. The text of the status bar goes away, but the box stays there.
  • kenny
    kenny about 2 years
    The follow minor change to obsolete API makes it work on Android. var activity = Xamarin.Essentials.Platform.CurrentActivity; var attrs = activity.Window.Attributes;