Определение языковой культуры

Последнее обновление: 14.01.2021

В прошлой теме был создан проект и ряд ресурсов, позволяющих локализовать приложение. Однако просто установки в коде нужного ресурса бывает недостаточно. Нужно явным образом указать требуемую языковую культуру для определенной платформы.

Поскольку каждая платформа требует определенного подхода, то нам надо использовать класс DependencyService, который позволит сопоставить нужные зависимости.

Вначале добавим в главный проект интерфейс ILocalize:

using System.Globalization;
public interface ILocalize
{
    CultureInfo GetCurrentCultureInfo();
}

Его единственный метод будет определять языковую культуру мобильного устройства.

Теперь добавим в проект для iOS следующий класс Localize:

using Foundation;
using Xamarin.Forms;
[assembly: Dependency(typeof(HelloApp.iOS.Localize))]
namespace HelloApp.iOS
{
    public class Localize : ILocalize
    {
        public System.Globalization.CultureInfo GetCurrentCultureInfo()
        {
            var netLanguage = "en";
            var prefLanguage = "en-US";
            if (NSLocale.PreferredLanguages.Length > 0)
            {
                var pref = NSLocale.PreferredLanguages[0];
                netLanguage = pref.Replace("_", "-"); // заменяет pt_BR на pt-BR
            }
            System.Globalization.CultureInfo ci = null;
            try
            {
                ci = new System.Globalization.CultureInfo(netLanguage);
            }
            catch
            {
                ci = new System.Globalization.CultureInfo(prefLanguage);
            }
            return ci;
        }
    }
}

Реализация этого класса использует массив NSLocale.PreferredLanguages для определения языковой культуры.

При получении языка на устройстве iOS нам следует учитывать следующий аспект. Пользователь теоретически может установить в качестве культуры, например, "en-ES". Например, если пользователь живет в Испании и в качестве региона выставил Испанию, однако захотел в качестве языка использовать английский. Культура "en-ES" не соответствует ни однйо из культур в .NET, поэтому программа может вывалиться в ошибку. Чтобы ее избежать, здесь применяется блок try...catch, где в случае неудачи получить установленную культуры мы получаем предпочтительную культуру - "en-US".

Некоторые системные элементы управления iOS переводит автоматически (например, элемент Picker). Но чтобы указать системе на необходимость перевода, нам надо внести в файл Info.plist, который имеется в проекте, соответствующие определения языковых культур. Info.plist представляет обычный xml-файл, поэтому откроем его в каком-нибудь текстовом редакторе. Он выглядит примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
  <!---->
  </dict>
</plist>

В пределах элемента dict добавим определения языков. В моем случае язык по умолчанию английский (en) и две дополнительных языковых культуры: русскоязычная (ru) и немецкая (de). Поэтому я добавляю следующие строки:

<key>CFBundleLocalizations</key>
<array>
	<string>de</string>
	<string>ru</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>

Настройка проекта для Android

В проект для Androida добавим следующий класс:

using Xamarin.Forms;
[assembly: Dependency(typeof(HelloApp.Droid.Localize))]
namespace HelloApp.Droid
{
    public class Localize : ILocalize
    {
        public System.Globalization.CultureInfo GetCurrentCultureInfo()
        {
            var androidLocale = Java.Util.Locale.Default;
            var netLanguage = androidLocale.ToString().Replace("_", "-");
            return new System.Globalization.CultureInfo(netLanguage);
        }
    }
}

Опять же это реализация интерфейса ILocalize, которая использует объект Java.Util.Locale.Default для определения культуры.

Настройка проекта для UWP

Также добавим реалзицию интерфейса ILocalize в проект для UWP:

using System.Globalization;
using Xamarin.Forms;
[assembly: Dependency(typeof(HelloApp.UWP.Localize))]
namespace HelloApp.UWP
{
    public class Localize : ILocalize
    {
        public System.Globalization.CultureInfo GetCurrentCultureInfo()
        {
            return CultureInfo.CurrentUICulture;
        }
    }
}

Языковая культура приложения должна определяться как можно раньше. В частности, это можно сделать при открытии стартовой страницы приложения. Итак, добавим в конструктор класса App в главном проекте определения языковой культуры:

public partial class App : Application
{
    public App()
    {
		InitializeComponent();
		
        if (Device.RuntimePlatform != Device.UWP)
        {
            Resource.Culture = DependencyService.Get<ILocalize>()
                                .GetCurrentCultureInfo();
        }
        MainPage = new MainPage();
    }
}

И поскольку фреймворк автоматически распознает язык на устройстве Windows 10, нам нет нужды устанавливать его вручную, поэтому сначала в коде проверяем тип платформы if (Device.RuntimePlatform != Device.UWP)

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850