如何在 Xamarin.Forms 中检查暗模式 [英] How to Check For Dark Mode in Xamarin.Forms

查看:21
本文介绍了如何在 Xamarin.Forms 中检查暗模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在 iOS 13Android Q 允许用户在操作系统级别启用暗模式,我如何检查它在 Xamarin.Forms 中?

Now that iOS 13 and Android Q allow the user to enable Dark Mode at the operating system level, how can I check for it in Xamarin.Forms?

我在我的 Xamarin.Forms 项目中创建了它,但我不确定如何从 Xamarin.iOS 和 Xamarin.Android 检索值.

I've created this in my Xamarin.Forms project, but I'm not sure how to retrieve the values from Xamarin.iOS and Xamarin.Android.

using System.Threading.Tasks;

namespace MyNamespace
{
    public interface IEnvironment
    {
        Theme GetOperatingSystemTheme();
        Task<Theme> GetOperatingSystemThemeAsync();
    }

    public enum Theme { Light, Dark }
}

App.cs

using Xamarin.Forms;

namespace MyNamespace
{
    public App : Application
    {
        // ...

        protected override async void OnStart()
        {
            base.OnStart();

            Theme theme = DependencyService.Get<IEnvironment>().GetOperatingSystemTheme();

            SetTheme(theme);
        }

        protected override async void OnResume()
        {
            base.OnResume();

            Theme theme = DependencyService.Get<IEnvironment>().GetOperatingSystemTheme();

            SetTheme(theme);
        }

        void SetTheme(Theme theme)
        {
            //Handle Light Theme & Dark Theme
        }
    }
}

推荐答案

我们可以使用 Xamarin.Forms 依赖服务从 iOS 和 Android 访问特定于平台的代码.

We can use the Xamarin.Forms dependency service to access the platform-specific code from iOS and Android.

我在这篇博文中进行了更深入的介绍:https://codetraveler.io/2019/09/10/check-for-dark-mode-in-xamarin-forms/

I've gone into more depth here in this blog post: https://codetraveler.io/2019/09/10/check-for-dark-mode-in-xamarin-forms/

using System.Threading.Tasks;

namespace MyNamespace
{
    public interface IEnvironment
    {
        Theme GetOperatingSystemTheme();
        Task<Theme> GetOperatingSystemThemeAsync();
    }

    public enum Theme { Light, Dark }
}

App.cs

using Xamarin.Forms;

namespace MyNamespace
{
    public App : Application
    {
        // ...

        protected override async void OnStart()
        {
            base.OnStart();

            Theme theme = DependencyService.Get<IEnvironment>().GetOperatingSystemTheme();

            SetTheme(theme);
        }

        protected override async void OnResume()
        {
            base.OnResume();

            Theme theme = DependencyService.Get<IEnvironment>().GetOperatingSystemTheme();

            SetTheme(theme);
        }

        void SetTheme(Theme theme)
        {
            //Handle Light Theme & Dark Theme
        }
    }
}

Xamarin.iOS

using System;
using UIKit;
using Xamarin.Forms;
using MyNamespace;
using MyNamespace.iOS;

[assembly: Dependency(typeof(Environment_iOS))]
namespace MyNamespace.iOS
{
    public class Environment_iOS : IEnvironment
    { 
        public Theme GetOperatingSystemTheme()
        {
            //Ensure the current device is running 12.0 or higher, because `TraitCollection.UserInterfaceStyle` was introduced in iOS 12.0
            if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
            {
                var currentUIViewController = GetVisibleViewController();

                var userInterfaceStyle = currentUIViewController.TraitCollection.UserInterfaceStyle;

                switch (userInterfaceStyle)
                {
                    case UIUserInterfaceStyle.Light:
                        return Theme.Light;
                    case UIUserInterfaceStyle.Dark:
                        return Theme.Dark;
                    default:
                        throw new NotSupportedException($"UIUserInterfaceStyle {userInterfaceStyle} not supported");
                }
            }
            else
            {
                return Theme.Light;
            }
        }

        // UIApplication.SharedApplication can only be referenced by the Main Thread, so we'll use Device.InvokeOnMainThreadAsync which was introduced in Xamarin.Forms v4.2.0
        public async Task<Theme> GetOperatingSystemThemeAsync() =>
            Device.InvokeOnMainThreadAsync(GetOperatingSystemTheme);

        static UIViewController GetVisibleViewController()
        {
            UIViewController viewController = null;

            var window = UIApplication.SharedApplication.KeyWindow;

            if (window.WindowLevel == UIWindowLevel.Normal)
                viewController = window.RootViewController;

            if (viewController is null)
            {
                window = UIApplication.SharedApplication
                    .Windows
                    .OrderByDescending(w => w.WindowLevel)
                    .FirstOrDefault(w => w.RootViewController != null && w.WindowLevel == UIWindowLevel.Normal);

                if (window is null)
                    throw new InvalidOperationException("Could not find current view controller.");

                viewController = window.RootViewController;
            }

            while (viewController.PresentedViewController != null)
                viewController = viewController.PresentedViewController;

            return viewController;
        }
    }
}

Xamarin.Android

using System;
using System.Threading.Tasks;
using Android.Content.Res;
using Plugin.CurrentActivity;
using Xamarin.Forms;

using MyNamespace;
using MyNamespace.Android;

[assembly: Dependency(typeof(Environment_Android))]
namespace MyNamespace.Android
{
    public class Environment_Android : IEnvironment
    {
        public Task<Theme> GetOperatingSystemThemeAsync()  =>
            Task.FromResult(GetOperatingSystemTheme());

        public Theme GetOperatingSystemTheme()
        {
            //Ensure the device is running Android Froyo or higher because UIMode was added in Android Froyo, API 8.0
            if(Build.VERSION.SdkInt >= BuildVersionCodes.Froyo)
            {
                var uiModeFlags = CrossCurrentActivity.Current.AppContext.Resources.Configuration.UiMode & UiMode.NightMask;

                switch(uiModelFlags)
                {
                    case UiMode.NightYes:
                        return Theme.Dark;

                    case UiMode.NightNo:
                        return Theme.Light;

                    default:
                        throw new NotSupportedException($"UiMode {uiModelFlags} not supported");
                }
            }
            else
            {
                return Theme.Light;
            }
        }
    }
}

这篇关于如何在 Xamarin.Forms 中检查暗模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆