Udostępnij za pośrednictwem


Xamarin.Forms Lokalizacja ciągów i obrazów

Lokalizacja to proces dostosowywania aplikacji w celu spełnienia określonych wymagań językowych lub kulturowych rynku docelowego. Aby przeprowadzić lokalizację, może być konieczne tłumaczenie tekstu i obrazów w aplikacji na wiele języków. Zlokalizowana aplikacja automatycznie wyświetla przetłumaczony tekst na podstawie ustawień kultury urządzenia przenośnego:

Zrzuty ekranu aplikacji lokalizacyjnej w systemach iOS i Android

Platforma .NET framework zawiera wbudowany mechanizm lokalizowania aplikacji przy użyciu plików zasobów Resx. Plik zasobu przechowuje tekst i inną zawartość jako pary nazwa/wartość, które umożliwiają aplikacji pobieranie zawartości dla podanego klucza. Pliki zasobów umożliwiają oddzielenie zlokalizowanej zawartości od kodu aplikacji.

Używanie plików zasobów do lokalizowania Xamarin.Forms aplikacji wymaga wykonania następujących kroków:

  1. Utwórz pliki Resx zawierające przetłumaczony tekst.
  2. Określ domyślną kulturę w projekcie udostępnionym.
  3. Lokalizowanie tekstu w pliku Xamarin.Forms.
  4. Lokalizowanie obrazów na podstawie ustawień kultury dla każdej platformy.
  5. Lokalizuj nazwę aplikacji na każdej platformie.
  6. Testowanie lokalizacji na każdej platformie.

Tworzenie plików Resx

Pliki zasobów to pliki XML z rozszerzeniem resx , które są kompilowane w plikach zasobów binarnych (.resources) podczas procesu kompilacji. Program Visual Studio 2019 generuje klasę, która udostępnia interfejs API używany do pobierania zasobów. Zlokalizowana aplikacja zazwyczaj zawiera domyślny plik zasobów ze wszystkimi ciągami używanymi w aplikacji, a także plikami zasobów dla każdego obsługiwanego języka. Przykładowa aplikacja ma folder Resx w udostępnionym projekcie zawierającym pliki zasobów i jego domyślny plik zasobu o nazwie AppResources.resx.

Pliki zasobów zawierają następujące informacje dla każdego elementu:

  • Nazwa określa klucz używany do uzyskiwania dostępu do tekstu w kodzie.
  • Wartość określa przetłumaczony tekst.
  • Komentarz jest polem opcjonalnym zawierającym dodatkowe informacje.

Plik zasobu jest dodawany za pomocą okna dialogowego Dodawanie nowego elementu w programie Visual Studio 2019:

Dodawanie nowego zasobu w programie Visual Studio 2019

Po dodaniu pliku można dodać wiersze dla każdego zasobu tekstowego:

Określanie domyślnych zasobów tekstowych w pliku resx

Ustawienie listy rozwijanej Modyfikator dostępu określa, w jaki sposób program Visual Studio generuje klasę używaną do uzyskiwania dostępu do zasobów. Ustawienie modyfikatora dostępu na publiczny lub wewnętrzny powoduje wygenerowanie klasy z określonym poziomem ułatwień dostępu. Ustawienie modyfikatora dostępu na Brak generowania kodu nie generuje pliku klasy. Domyślny plik zasobu należy skonfigurować tak, aby wygenerować plik klasy, co powoduje dodanie pliku z rozszerzeniem .designer.cs do projektu.

Po utworzeniu domyślnego pliku zasobów można utworzyć dodatkowe pliki dla każdej kultury obsługiwanej przez aplikację. Każdy dodatkowy plik zasobu powinien zawierać kulturę tłumaczenia w nazwie pliku i powinien mieć modyfikator dostępu ustawiony na Wartość Brak generowania kodu.

W czasie wykonywania aplikacja próbuje rozwiązać żądanie zasobu w kolejności specyficznej. Jeśli na przykład kultura urządzenia to en-US , aplikacja szuka plików zasobów w następującej kolejności:

  1. AppResources.en-US.resx
  2. AppResources.en.resx
  3. AppResources.resx (ustawienie domyślne)

Poniższy zrzut ekranu przedstawia hiszpański plik tłumaczenia o nazwie AppResources.es.resx:

Określanie domyślnych zasobów tekstowych w języku hiszpańskim w pliku resx

Plik tłumaczenia używa tych samych wartości Nazwa określonych w pliku domyślnym, ale zawiera ciągi języka hiszpańskiego w kolumnie Wartość . Ponadto modyfikator dostępu ma wartość Brak generowania kodu.

Plik zasobu jest dodawany za pomocą okna dialogowego Dodawanie nowego pliku w programie Visual Studio 2019 dla komputerów Mac:

Dodawanie nowego zasobu w programie Visual Studio 2019 dla komputerów Mac

Po utworzeniu domyślnego pliku zasobu można dodać tekst, tworząc data elementy w root pliku zasobu:

<?xml version="1.0" encoding="utf-8"?>
<root>
    ...
    <data name="AddButton" xml:space="preserve">
        <value>Add Note</value>
    </data>
    <data name="NotesLabel" xml:space="preserve">
        <value>Notes:</value>
    </data>
    <data name="NotesPlaceholder" xml:space="preserve">
        <value>e.g. Get Milk</value>
    </data>
</root>

Plik klasy .designer.cs można utworzyć, ustawiając właściwość Narzędzia niestandardowego w opcjach pliku zasobu:

Narzędzie niestandardowe określone we właściwościach pliku zasobu

Ustawienie elementu Custom Tool na PublicResXFileCodeGenerator spowoduje wygenerowanie klasy z dostępem public . Ustawienie elementu Custom Tool na InternalResXFileCodeGenerator spowoduje wygenerowanie klasy z dostępem internal . Pusta wartość narzędzia niestandardowego nie wygeneruje klasy. Wygenerowana nazwa klasy będzie zgodna z nazwą pliku zasobu. Na przykład plik AppResources.resx spowoduje utworzenie AppResources klasy w pliku o nazwie AppResources.designer.cs.

Dodatkowe pliki zasobów można utworzyć dla każdej obsługiwanej kultury. Każdy plik języka powinien zawierać kulturę tłumaczenia w nazwie pliku, więc plik przeznaczony dla es-MX powinien mieć nazwę AppResources.es-MX.resx.

W czasie wykonywania aplikacja próbuje rozwiązać żądanie zasobu w kolejności specyficznej. Jeśli na przykład kultura urządzenia to en-US , aplikacja szuka plików zasobów w następującej kolejności:

  1. AppResources.en-US.resx
  2. AppResources.en.resx
  3. AppResources.resx (ustawienie domyślne)

Pliki tłumaczenia języka powinny mieć te same wartości Nazwa określone jako plik domyślny. Poniższy kod XML przedstawia hiszpański plik tłumaczenia o nazwie AppResources.es.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
    ...
    <data name="NotesLabel" xml:space="preserve">
        <value>Notas:</value>
    </data>
    <data name="NotesPlaceholder" xml:space="preserve">
        <value>por ejemplo . comprar leche</value>
    </data>
    <data name="AddButton" xml:space="preserve">
        <value>Agregar nuevo elemento</value>
    </data>
</root>

Określanie kultury domyślnej

Aby pliki zasobów działały poprawnie, aplikacja musi mieć NeutralResourcesLanguage określony atrybut. W projekcie zawierającym pliki zasobów plik AssemblyInfo.cs należy dostosować, aby określić kulturę domyślną. Poniższy kod pokazuje, jak ustawić NeutralResourcesLanguage wartość en-US w pliku AssemblyInfo.cs:

using System.Resources;

// The resources from the neutral language .resx file are stored directly
// within the library assembly. For that reason, changing en-US to a different
// language in this line will not by itself change the language shown in the
// app. See the discussion of UltimateResourceFallbackLocation in the
// documentation for additional information:
// https://learn.microsoft.com/dotnet/api/system.resources.neutralresourceslanguageattribute
[assembly: NeutralResourcesLanguage("en-US")]

Ostrzeżenie

Jeśli nie określisz atrybutu NeutralResourcesLanguage , ResourceManager klasa zwraca null wartości dla dowolnych kultur bez określonego pliku zasobu. Po określeniu ResourceManager kultury domyślnej zwraca wyniki z domyślnego pliku Resx dla nieobsługiwanych kultur. Dlatego zaleca się, aby zawsze określać, NeutralResourcesLanguage aby tekst był wyświetlany dla nieobsługiwanych kultur.

Po utworzeniu domyślnego pliku zasobu i domyślnej kultury określonej w pliku AssemblyInfo.cs aplikacja może pobierać zlokalizowane ciągi w czasie wykonywania.

Aby uzyskać więcej informacji na temat plików zasobów, zobacz Create resource files for .NET apps (Tworzenie plików zasobów dla aplikacji platformy .NET).

Określanie obsługiwanych języków w systemie iOS

W systemie iOS należy zadeklarować wszystkie obsługiwane języki w pliku Info.plist projektu. W pliku Info.plist użyj widoku Źródło, aby ustawić tablicę dla CFBundleLocalizations klucza i podać wartości odpowiadające plikom Resx. Ponadto upewnij się, że ustawiono oczekiwany język za pomocą CFBundleDevelopmentRegion klucza:

Zrzut ekranu edytora Info.plist przedstawiający sekcję Lokalizacje

Alternatywnie otwórz plik Info.plist w edytorze XML i dodaj następujące polecenie:

<key>CFBundleLocalizations</key>
<array>
    <string>de</string>
    <string>es</string>
    <string>fr</string>
    <string>ja</string>
    <string>pt</string> <!-- Brazil -->
    <string>pt-PT</string> <!-- Portugal -->
    <string>ru</string>
    <string>zh-Hans</string>
    <string>zh-Hant</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>

Uwaga

Apple traktuje Portugalczyka nieco inaczej niż można się spodziewać. Aby uzyskać więcej informacji, zobacz Dodawanie języków w developer.apple.com.

Aby uzyskać więcej informacji, zobacz Określanie domyślnych i obsługiwanych języków w pliku Info.plist.

Określanie obsługiwanych języków na platformie UWP

Jest to konieczne tylko w przypadku wygenerowania pakietu aplikacji podczas tworzenia pakietu aplikacji na potrzeby ładowania bezpośredniego lub sklepu. Podczas generowania pakietu aplikacji platformy UNIWERSALNEJ systemu Windows po zainstalowaniu pakietu zostaną załadowane tylko zasoby związane z ustawieniami języka urządzenia instalacyjnego. W związku z tym, jeśli urządzenie ma tylko angielski, tylko zasoby angielskie zostaną zainstalowane z aplikacją. Aby uzyskać więcej informacji i instrukcji, zobacz Aplikacje ze Sklepu Windows 8.1: Upewnij się, że zasoby są zainstalowane na urządzeniu niezależnie od tego, czy urządzenie ich wymaga.

Lokalizowanie tekstu w Xamarin.Forms

Tekst jest zlokalizowany przy Xamarin.Forms użyciu wygenerowanej AppResources klasy. Ta klasa ma nazwę opartą na domyślnej nazwie pliku zasobu. Ponieważ przykładowy plik zasobu projektu nosi nazwę AppResources.resx, program Visual Studio generuje zgodną klasę o nazwie AppResources. Właściwości statyczne są generowane w AppResources klasie dla każdego wiersza w pliku zasobu. Następujące właściwości statyczne są generowane w klasie przykładowej AppResources aplikacji:

  • Addbutton
  • NotesLabel
  • Symbol zastępczy notatek

Uzyskiwanie dostępu do tych wartości jako właściwości x:Static umożliwia wyświetlanie zlokalizowanego tekstu w języku XAML:

<ContentPage ...
             xmlns:resources="clr-namespace:LocalizationDemo.Resx">
    <Label Text="{x:Static resources:AppResources.NotesLabel}" />
    <Entry Placeholder="{x:Static resources:AppResources.NotesPlaceholder}" />
    <Button Text="{x:Static resources:AppResources.AddButton}" />
</ContentPage>

Zlokalizowany tekst można również pobrać w kodzie:

public LocalizedCodePage()
{
    Label notesLabel = new Label
    {
        Text = AppResources.NotesLabel,
        // ...
    };

    Entry notesEntry = new Entry
    {
        Placeholder = AppResources.NotesPlaceholder,
        //...
    };

    Button addButton = new Button
    {
        Text = AppResources.AddButton,
        // ...
    };

    Content = new StackLayout
    {
        Children = {
            notesLabel,
            notesEntry,
            addButton
        }
    };
}

Właściwości w AppResources klasie używają bieżącej System.Globalization.CultureInfo.CurrentUICulture wartości elementu , aby określić, z którego pliku zasobu kultury mają być pobierane wartości.

Lokalizowanie obrazów

Oprócz przechowywania tekstu pliki Resx mogą przechowywać więcej niż tylko tekst, mogą również przechowywać obrazy i dane binarne. Jednak urządzenia przenośne mają szereg rozmiarów i gęstości ekranu, a każda platforma mobilna ma funkcje wyświetlania obrazów zależnych od gęstości. W związku z tym należy użyć funkcji lokalizacji obrazu platformy zamiast przechowywania obrazów w plikach zasobów.

Lokalizowanie obrazów w systemie Android

W systemie Android zlokalizowane elementy rysowalne (obrazy) są przechowywane przy użyciu konwencji nazewnictwa folderów w katalogu Resources . Foldery mają nazwę rysowalne z sufiksem języka docelowego. Na przykład folder języka hiszpańskiego nosi nazwę drawable-es.

Gdy wymagany jest czteroliterowy kod ustawień regionalnych, system Android wymaga dodatkowego r po kreski. Na przykład folder Ustawienia regionalne Meksyku (es-MX) powinien mieć nazwę drawable-es-rMX. Nazwy plików obrazów w każdym folderze ustawień regionalnych powinny być identyczne:

Zlokalizowane obrazy w projekcie systemu Android

Aby uzyskać więcej informacji, zobacz Lokalizacja systemu Android.

Lokalizowanie obrazów w systemie iOS

W systemie iOS zlokalizowane obrazy są przechowywane przy użyciu konwencji nazewnictwa folderów w katalogu Resources . Folder domyślny nosi nazwę Base.lproj. Foldery specyficzne dla języka mają nazwę z nazwą języka lub ustawień regionalnych, a następnie .lproj. Na przykład folder języka hiszpańskiego nosi nazwę es.lproj.

Kody lokalne z czterema literami działają podobnie jak dwuliterowe kody językowe. Na przykład folder Ustawienia regionalne Meksyku (es-MX) powinien mieć nazwę es-MX.lproj. Nazwy plików obrazów w każdym folderze ustawień regionalnych powinny być identyczne:

Zlokalizowane obrazy w projekcie systemu iOS

Uwaga

System iOS obsługuje tworzenie zlokalizowanego wykazu zasobów zamiast używać struktury folderów lproj. Należy je jednak utworzyć i zarządzać nimi w środowisku Xcode.

Aby uzyskać więcej informacji, zobacz Lokalizacja systemu iOS.

Lokalizowanie obrazów na platformie UWP

Na platformie UWP zlokalizowane obrazy są przechowywane przy użyciu konwencji nazewnictwa folderów w katalogu Assets/Images . Foldery mają nazwę z językiem lub ustawieniami regionalnymi. Na przykład folder języka hiszpańskiego nosi nazwę es , a folder ustawień regionalnych Meksyku powinien mieć nazwę es-MX. Nazwy plików obrazów w każdym folderze ustawień regionalnych powinny być identyczne:

Zlokalizowane obrazy w projekcie platformy UWP

Aby uzyskać więcej informacji, zobacz Lokalizacja platformy UWP.

Korzystanie z zlokalizowanych obrazów

Ponieważ każda platforma przechowuje obrazy z unikatową strukturą plików, język XAML używa OnPlatform klasy do ustawiania ImageSource właściwości na podstawie bieżącej platformy:

<Image>
    <Image.Source>
        <OnPlatform x:TypeArguments="ImageSource">
            <On Platform="iOS, Android" Value="flag.png" />
            <On Platform="UWP" Value="Assets/Images/flag.png" />
        </OnPlatform>
    </Image.Source>
</Image>

Uwaga

OnPlatform Rozszerzenie znaczników oferuje bardziej zwięzły sposób określania wartości specyficznych dla platformy. Aby uzyskać więcej informacji, zobacz OnPlatform markup extension (Rozszerzenie znaczników OnPlatform).

Źródło obrazu można ustawić na Device.RuntimePlatform podstawie właściwości w kodzie:

string imgSrc = Device.RuntimePlatform == Device.UWP ? "Assets/Images/flag.png" : "flag.png";
Image flag = new Image
{
    Source = ImageSource.FromFile(imgSrc),
    WidthRequest = 100
};

Lokalizowanie nazwy aplikacji

Nazwa aplikacji jest określona na platformę i nie używa plików zasobów Resx. Aby zlokalizować nazwę aplikacji w systemie Android, zobacz Localize app name on Android (Lokalizowanie nazwy aplikacji w systemie Android). Aby zlokalizować nazwę aplikacji w systemie iOS, zobacz Localize app name on iOS (Lokalizowanie nazwy aplikacji w systemie iOS). Aby zlokalizować nazwę aplikacji na platformie UWP, zobacz Lokalizowanie ciągów w manifeście pakietu platformy UWP.

Lokalizacja testowa

Najlepiej przeprowadzić testowanie lokalizacji przez zmianę języka urządzenia. Istnieje możliwość ustawienia wartości System.Globalization.CultureInfo.CurrentUICulture w kodzie, ale zachowanie jest niespójne na różnych platformach, dlatego nie jest to zalecane do testowania.

W systemie iOS w aplikacji ustawień można ustawić język dla każdej aplikacji, w szczególności bez zmieniania języka urządzenia.

W systemie Android ustawienia języka są wykrywane i buforowane po uruchomieniu aplikacji. W przypadku zmiany języków może być konieczne zamknięcie i ponowne uruchomienie aplikacji w celu wyświetlenia zastosowanych zmian.