Xamarin Forms - как изменить цвет строки состояния без навигационной страницы - PullRequest
2 голосов
/ 18 октября 2019

Я хочу изменить цвет строки состояния в некоторых представлениях.

Я нашел это решение https://github.com/yuv4ik/XFDynamicStatusBarAppearance

, но оно работает только с NavigationPage.

Не знаюМне нужно из моего приложения Страница навигации ...

    public App()
    {
        InitializeComponent();

        MainPage = new MainPage();
    }

Вот моя попытка ...

    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;
        }

    };

Как изменить цвет строки состояния?

Ответы [ 2 ]

1 голос
/ 21 октября 2019

Вот мое рабочее решение на обеих платформах ...

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

Настройте цвет строки состояния с помощью этой строки

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

или вы можете оставить его белым с черным цветом шрифта

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;
        }
    }
}

Полный рабочий образец здесь https://github.com/georgemichailou/ShaXam

1 голос
/ 18 октября 2019

Вы можете попробовать добавить этот код на платформе Android, метод OnCreate:

 protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

        LoadApplication(new App());
       Window.SetStatusBarColor(Android.Graphics.Color.Argb(255, 0, 0, 0)); //here

    }

Обратите внимание, что SetStatusBarColor поддерживается только в API уровня 21 и выше. Поэтому мы должны проверить это перед вызовом SetStatusBarColor.

if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)

  {
   Window.SetStatusBarColor(...);
  }

Обновление:

Создание интерфейса в PCL:

public  interface IStatusBarColor
{
    void changestatuscolor(string color);
}

Теперь Mainactivity реализует этот интерфейс.

[assembly: Dependency(typeof(demo2.Droid.MainActivity))]
 namespace demo2.Droid
 {
[Activity(Label = "demo2", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity,IStatusBarColor
{

    public static Context context;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

        LoadApplication(new App());

    }



    public void changestatuscolor(string color)
    {
        if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
        {
            var c = MainActivity.context as FormsAppCompatActivity;
            c?.RunOnUiThread(() => c.Window.SetStatusBarColor(Android.Graphics.Color.ParseColor(color)));
        }

    }
    protected override void OnResume()
    {
        context = this;
        base.OnResume();
    }

}

}

На главной странице, чтобы изменить цвет строки состояния в событии нажатия кнопки.

 private void Changecolor_Clicked(object sender, EventArgs e)
    {
        DependencyService.Get<IStatusBarColor>().changestatuscolor(Color.Red.ToHex());
    }

enter image description here

...