Какие существуют подходы к локализации приложения?
Локализация приложения — это процесс адаптации интерфейса, текста, форматов дат, валют и других культурных аспектов под различные языки и регионы. В Xamarin и Xamarin.Forms для локализации используются стандартные .NET-механизмы на базе ресурсных файлов (RESX), а также платформенные инструменты. Локализация обеспечивает удобство использования приложения пользователями, говорящими на разных языках, и играет важную роль в международных и коммерческих проектах.
Основные подходы к локализации в Xamarin.Forms
-
Использование .resx-файлов (ресурсных файлов) с переводами.
-
Использование платформенных инструментов локализации на Android и iOS.
-
Настройка определения и переключения текущей культуры.
-
Возможность динамической локализации — смены языка во время работы приложения (с дополнительными настройками).
-
Поддержка форматирования по культуре: чисел, дат, валют.
1. Создание ресурсных файлов (RESX)
Ресурсные файлы — это файлы формата .resx, содержащие пары ключ-значение, где:
-
ключ — идентификатор текста (WelcomeMessage)
-
значение — текст на конкретном языке (Добро пожаловать, Welcome, Willkommen и т.д.)
Структура:
Resources/
├── AppResources.resx (по умолчанию, например русский)
├── AppResources.en.resx (английский)
├── AppResources.es.resx (испанский)
Добавить можно через Visual Studio:
-
Щёлкните правой кнопкой по проекту → Add → New Item... → Resources File
-
Назовите AppResources.resx, затем скопируйте и добавьте версии для других языков (AppResources.fr.resx и т.д.)
2. Доступ к строкам из C#
string welcome = AppResources.WelcomeMessage;
Чтобы получить доступ к нужной локализации, нужно установить культуру.
3. Установка культуры (CultureInfo)
Для установки текущей культуры используется CultureInfo из пространства имён System.Globalization.
Пример установки культуры:
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
Для Xamarin.Forms лучше использовать глобальную установку при запуске приложения.
4. Реализация ILocalize через DependencyService
Чтобы получить текущую культуру устройства, нужно создать интерфейс ILocalize:
public interface ILocalize
{
CultureInfo GetCurrentCultureInfo();
}
Android:
\[assembly: Dependency(typeof(Localize_Android))\]
namespace MyApp.Droid
{
public class Localize_Android : ILocalize
{
public CultureInfo GetCurrentCultureInfo()
{
var androidLocale = Java.Util.Locale.Default;
var netLocale = androidLocale.ToString().Replace("\_", "-");
return new CultureInfo(netLocale);
}
}
}
iOS:
\[assembly: Dependency(typeof(Localize_iOS))\]
namespace MyApp.iOS
{
public class Localize_iOS : ILocalize
{
public CultureInfo GetCurrentCultureInfo()
{
var iosLocale = NSLocale.PreferredLanguages\[0\];
return new CultureInfo(iosLocale.Replace("\_", "-"));
}
}
}
Применение:
var ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo();
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = ci;
5. Локализация в XAML
Чтобы использовать ресурсы в XAML, нужно их подключить как xmlns.
Пример подключения ресурсов:
xmlns:resx="clr-namespace:MyApp.Resources"
Использование:
<Label Text="{x:Static resx:AppResources.WelcomeMessage}" />
Если используется x:Static не поддерживаемый в XAML версии Xamarin.Forms, можно использовать Binding через LocalizationResourceManager.
6. Альтернативный подход: LocalizationResourceManager
Чтобы упростить локализацию в XAML, можно использовать LocalizationResourceManager, как часть собственного INotifyPropertyChanged класса, позволяющего менять язык динамически.
Пример:
public class LocalizationResourceManager : INotifyPropertyChanged
{
public static LocalizationResourceManager Instance { get; } = new LocalizationResourceManager();
public string this\[string text\]
{
get => AppResources.ResourceManager.GetString(text, AppResources.Culture);
}
public void SetCulture(CultureInfo culture)
{
AppResources.Culture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
}
public event PropertyChangedEventHandler PropertyChanged;
}
И в XAML:
<Label Text="{Binding Source={x:Static res:LocalizationResourceManager.Instance}, Path=\[WelcomeMessage\]}" />
7. Переключение языка во время работы приложения
Чтобы язык приложения можно было сменить вручную (например, через настройки), необходимо:
-
Сохранить выбранный язык в Preferences.
-
При загрузке приложения — применять сохранённый язык.
-
Повторно применять SetCulture(...) и обновлять интерфейс.
Пример смены языка:
LocalizationResourceManager.Instance.SetCulture(new CultureInfo("es"));
8. Локализация платформенных элементов
На Android и iOS есть платформенные элементы, которые не управляются через RESX. Для них:
Android:
-
Файлы находятся в Resources/values/strings.xml, values-es/strings.xml и т.д.
-
Их можно использовать в платформенной части или через Custom Renderers.
iOS:
- Используется Localizable.strings, добавляемый в Resources.
Пример:
"WelcomeMessage" = "Bienvenido";
9. Локализация форматов данных
Культура влияет на:
-
Формат даты и времени
-
Формат чисел (разделители, валюты)
-
Формат отображения текста (направление, региональные различия)
Пример:
DateTime now = DateTime.Now;
string formatted = now.ToString("D", CultureInfo.CurrentCulture);
10. Поддержка RTL (Right-to-Left)
Для языков с письмом справа налево (арабский, иврит):
- Установите FlowDirection:
<StackLayout FlowDirection="RightToLeft">
...
</StackLayout>
- Xamarin.Forms 4.0+ поддерживает FlowDirection глобально:
Application.Current.MainPage.FlowDirection = FlowDirection.RightToLeft;
11. Тестирование локализации
-
Эмулируйте разные языки на устройствах или эмуляторах.
-
Используйте App Resources и ключи, чтобы видеть, какой текст загружается.
-
Не хардкодьте строки в XAML и C#.
12. Советы по организации локализации
-
Используйте одинаковые ключи во всех .resx.
-
Для длинных строк используйте многострочные значения в .resx.
-
Храните строки для ошибок, сообщений, заголовков — всё в ресурсах.
-
Для каждого языка создавайте отдельный .resx (AppResources.fr.resx и т.п.)
-
Можно использовать сторонние сервисы для перевода .resx файлов (POEditor, Crowdin).
13. Локализация в .NET MAUI
В MAUI подход схожий, но LocalizationResourceManager включён в CommunityToolkit.Maui, что упрощает реализацию. Большая часть кода из Xamarin переносится с минимальными изменениями.