Search code examples
c#xamarinxamarin.formsxamarin.androidxamarin.ios

How to change the status bar color without a navigation page


I want to change the status bar color on some views.

I found this solution https://github.com/yuv4ik/XFDynamicStatusBarAppearance

but it's working only with NavigationPage.

I don't need from my app Navigation Page ...

    public App()
    {
        InitializeComponent();

        MainPage = new MainPage();
    }

Here is my try ...

    var statusBarStyleManager = DependencyService.Get<IStatusBarStyleManager>();

    MainCarousel.PositionChanged += (sender, e) =>
    {
        switch (e.CurrentPosition)
        {
            case 1:
                Device.BeginInvokeOnMainThread(() =>
                {
                    Xamarin.Forms.Application.Current.MainPage.SetValue(Xamarin.Forms.NavigationPage.BarBackgroundColorProperty, Color.DarkCyan);

                    //((Xamarin.Forms.NavigationPage)Xamarin.Forms.Application.Current.MainPage).BarBackgroundColor = Color.DarkCyan;
                    statusBarStyleManager.SetDarkTheme();
                });
                break;
            case 0:
            case 2:
                Device.BeginInvokeOnMainThread(() =>
                {
                    Xamarin.Forms.Application.Current.MainPage.SetValue(Xamarin.Forms.NavigationPage.BarBackgroundColorProperty, Color.LightGreen);
                    statusBarStyleManager.SetLightTheme();
                });
                break;
            default:
                break;
        }
    };

How can I change the status bar color ?


Solution

  • Here is my working solution on both platforms ...

    public interface IStatusBarStyleManager
    {
        void SetColoredStatusBar(string hexColor);
        void SetWhiteStatusBar();
    }
    

    Setup the Status bar color with this line

    DependencyService.Get<IStatusBarStyleManager>().SetColoredStatusBar("#2196F3");
    

    or you can keep it white with black font color

    DependencyService.Get<IStatusBarStyleManager>().SetWhiteStatusBar();
    

    Android

    [assembly: Xamarin.Forms.Dependency(typeof(StatusBarStyleManager))]
    namespace ShaXam.Droid.DependencyServices
    {
        public class StatusBarStyleManager : IStatusBarStyleManager
        {
            public void SetColoredStatusBar(string hexColor)
            {
                if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        var currentWindow = GetCurrentWindow();
                        currentWindow.DecorView.SystemUiVisibility = 0;
                        currentWindow.SetStatusBarColor(Android.Graphics.Color.ParseColor(hexColor);
                    });
                }
            }
    
            public void SetWhiteStatusBar()
            {
                if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        var currentWindow = GetCurrentWindow();
                        currentWindow.DecorView.SystemUiVisibility = (StatusBarVisibility)SystemUiFlags.LightStatusBar;
                        currentWindow.SetStatusBarColor(Android.Graphics.Color.White);
                    });
                }
            }
    
            Window GetCurrentWindow()
            {
                var window = CrossCurrentActivity.Current.Activity.Window;
    
                // clear FLAG_TRANSLUCENT_STATUS flag:
                window.ClearFlags(WindowManagerFlags.TranslucentStatus);
    
                // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
                window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
    
                return window;
            }
        }
    }
    

    iOS

    [assembly: Dependency(typeof(StatusBarStyleManager))]
    namespace ShaXam.iOS.DependencyServices
    {
        public class StatusBarStyleManager : IStatusBarStyleManager
        {
            public void SetColoredStatusBar(string hexColor)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
                    if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
                    {
                        statusBar.BackgroundColor = Color.FromHex(hexColor).ToUIColor();
                    }
                    UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.LightContent, false);
                    GetCurrentViewController().SetNeedsStatusBarAppearanceUpdate();
                });
            }
    
            public void SetWhiteStatusBar()
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
                    if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
                    {
                        statusBar.BackgroundColor = UIColor.White;
                    }
                    UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.Default, false);
                    GetCurrentViewController().SetNeedsStatusBarAppearanceUpdate();
                });
            }
    
            UIViewController GetCurrentViewController()
            {
                var window = UIApplication.SharedApplication.KeyWindow;
                var vc = window.RootViewController;
                while (vc.PresentedViewController != null)
                    vc = vc.PresentedViewController;
                return vc;
            }
        }
    }
    

    POST UPDATED TO SUPPORT THE IOS 13

    [assembly: Dependency(typeof(StatusBarStyleManager))]
    namespace ShaXam.iOS.DependencyServices
    {
        public class StatusBarStyleManager : IStatusBarStyleManager
        {
            public void SetColoredStatusBar(string hexColor)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
                    {
                        UIView statusBar = new UIView(UIApplication.SharedApplication.KeyWindow.WindowScene.StatusBarManager.StatusBarFrame);
                        statusBar.BackgroundColor = Color.FromHex(hexColor).ToUIColor();
                        UIApplication.SharedApplication.KeyWindow.AddSubview(statusBar);
                    }
                    else
                    {
                        UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
                        if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
                        {
                            statusBar.BackgroundColor = Color.FromHex(hexColor).ToUIColor();
                        }
                    }
                    UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.LightContent, false);
                    GetCurrentViewController().SetNeedsStatusBarAppearanceUpdate();
                });
            }
    
            public void SetWhiteStatusBar()
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
                    {
                        UIView statusBar = new UIView(UIApplication.SharedApplication.KeyWindow.WindowScene.StatusBarManager.StatusBarFrame);
                        statusBar.BackgroundColor = UIColor.White;
                        UIApplication.SharedApplication.KeyWindow.AddSubview(statusBar);
                    }
                    else
                    {
                        UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
                        if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
                        {
                            statusBar.BackgroundColor = UIColor.White;
                        }
                    }
                    UIApplication.SharedApplication.SetStatusBarStyle(UIStatusBarStyle.DarkContent, false);
                    GetCurrentViewController().SetNeedsStatusBarAppearanceUpdate();
                });
            }
    
            UIViewController GetCurrentViewController()
            {
                var window = UIApplication.SharedApplication.KeyWindow;
                var vc = window.RootViewController;
                while (vc.PresentedViewController != null)
                    vc = vc.PresentedViewController;
                return vc;
            }
        }
    }
    

    The full working sample is here https://github.com/georgemichailou/ShaXam