0

I am building a cross platform app using Xamarin forms on a mac using Visual code for mac.

I need to be able to change the status bar text and background colors on both the iOS and Android version of the APP.

I tried James Montemagno's solution from his video. https://www.youtube.com/watch?v=GKJRR8_DSSs

So every thing was good till we needed to use this code window.DecorView.SystemUiVisibility This code is deprecated and Visual Studio does not offert any hint to what I can use instead. I have tried to find but all I get is Android native related information 1.

I really wish I would not have to use "native" code for some thing so basic in mobile App development. I understand that using the Shell class will allow me do use the minimal amount of "native" code possible, really wish to avoid coding any native code if possibly.

Context: I need to set the Android version of the app so that is has a white status bar and black text. Also I have 1 page with a black background image taking the full view, so on this page I need the status bar to be transparent and use a white foreground color.

So what does replace window.DecorView.SystemUiVisibility = darkStatusBarTint ? flag : 0; ??

The app is targeting Android API 30.

This is the code that is in the video

From main project stub
    using System;
    using System.Drawing;
    
    namespace MyApp.Helpers
    {
        public interface IEnvironment
        {
            void SetStatusBarColor(Color color, bool darkStatusBarTint);
        }
    }

From android stub
    using System;
    using System.Drawing;
    using System.Runtime.CompilerServices;
    using Android.OS;
    using EGrid18.Helpers;
    using Xamarin.Essentials;
    using Xamarin.Forms;
    using Color = System.Drawing.Color;
    using DependencyAttribute = Xamarin.Forms.DependencyAttribute;
    
    [assembly: Dependency(typeof(MyApp.Droid.Environment))]
    namespace MyApp.Droid
    {
        public class Environment: IEnvironment
        {
            
            public void SetStatusBarColor(Color color, bool darkStatusBarTint)
            {
                if (Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
                    return;
                var activity = Platform.CurrentActivity;
                var window = activity.Window;
                window.AddFlags(Android.Views.WindowManagerFlags.DrawsSystemBarBackgrounds);
                window.ClearFlags(Android.Views.WindowManagerFlags.TranslucentStatus);
                window.SetStatusBarColor(color.ToPlatformColor());
    
                if(Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M)
                {
                    var flag = (Android.Views.StatusBarVisibility)Android.Views.SystemUiFlags.LightStatusBar;
    #pragma warning disable CS0618 // Le type ou le membre est obsolète
                    //problen is here
                    window.DecorView.SystemUiVisibility = darkStatusBarTint ? flag : 0;
    #pragma warning restore CS0618 // Le type ou le membre est obsolète
                }
            }
        }
    }
Pascale Beaulac
  • 889
  • 10
  • 28
  • 1
    *"all I get is Android native related information"* - Xamarin.Android c# code is 1:1 with corresponding native java/kotlin code. (all the same API calls; just different naming. Sometimes a property instead of get/set methods.) Have you tried to convert to c# the "native" code you found? If you are having trouble with that, **add to question** the link(s) you found, the relevant "native" code, and your best attempt at converting to c#. – ToolmakerSteve Nov 07 '22 at 22:19
  • Does this answer your question? https://stackoverflow.com/a/74115296/4308455 Or this? https://stackoverflow.com/a/74115296/4308455 By the way, there is always some level of native API code involved in cross-platform development as there are differences between platforms. – Julian Nov 15 '22 at 11:06

2 Answers2

0

As systemUiVisibility property is deprecated, you could use WindowInsetsControllerCompat. Refer to jamesmontemagno's MyCoffeeApp and try the following code:

WindowCompat.GetInsetsController(window, window.DecorView).AppearanceLightStatusBars = darkStatusBarTint;

That means if set AppearanceLightStatusBars to true, then changes the foreground color of the status bars to light so that the items on the bar can be read clearly.

For more information, you could see WindowInsetsControllerCompat

Hope it works for you.

Liqun Shen-MSFT
  • 3,490
  • 2
  • 3
  • 11
0

If you want to make sure that the status bar text and icons remain legible when you set the status bar color, then you can do the following:

public void SetSystemBarColor(Color color, bool lightStatusBarTheme)
{
    Window?.SetStatusBarColor(color);

    var statusBarFlags = lightStatusBarTheme ? (int)WindowInsetsControllerAppearance.LightStatusBars : 0;
    Window?.InsetsController?.SetSystemBarsAppearance(statusBarFlags, (int)WindowInsetsControllerAppearance.LightStatusBars);
}

Then call it as follows in your Activity:

//black status bar
SetSystemBarColor(Color.Black, false);

//white status bar
SetSystemBarColor(Color.White, true);
Julian
  • 5,290
  • 1
  • 17
  • 40