記事一覧

多言語化する方法 -ローカライズ- | Xamarin.Forms


今回はXamarin.Formsで多言語化する方法をご紹介いたします。尚、アプリケーションを多言語化対応することをローカライズと言います。
スマホには地域や言語を変更することにより表示する言語や時刻や通貨のフォーマット等を変更する機能が標準で付いています。よって、アプリを使用する日本人の場合は日本語を表示し、中国人の場合は中国語を表示できると、アプリも使われる幅が広がりますね。


xamarin_multilanguege_01.png


前提条件
・Windows10 Pro 64Bit
・Visual Studio 2015 Community Update3
・Xamarin 4.3.0.795 (NuGet Xamarin.Forms 2.3.4.247)
・macOS Sierra 10.12.4 / Xcode8.3.1 / Xamarin.iOS 10.6.0.10



1.メインの言語設定

メインとして設定する言語はPCLプロジェクト\Properties\AssemblyInfo.csに以下のように記載されています。

AssemblyInfo.cs
//日本語がメインの言語となるアプリの場合
[assembly: NeutralResourcesLanguage("ja-JP")]
//英語がメインの言語となるアプリの場合
[assembly: NeutralResourcesLanguage("en-US")]

※どちらかひとつしか記述できません。



2.AppResources.resx


xamarin_multilanguege_02.png

(1)図のように翻訳するファイル「AppResources.resx」をPCLプロジェクト\Resourcesフォルダ内に配置します。
ファイル名はAppResources.XX.resx とします。XXには翻訳したいカルチャー名を入力します。XXを付けないファイルの中にはメインの言語を記述します。

【カルチャー例】
スペイン語:es
フランス語:fr
ポルトガル語:pt
ロシア語:ru
韓国語:ko
中国語(簡体):zh-Hans
中国語(繁体):zh-Hant

※カルチャー名を間違えて設定すると言語が正しく表示されず、メインの言語が表示されます。


(2)次にAppResourcesファイル内に翻訳したい言葉とそのキーワードを入力します。

AppResources.ja.resx
<root>
  ・
  ・途中省略
  ・
  <data name="PageTitle" xml:space="preserve">
    <value>ページタイトル</value>
    <comment>タイトルの備考</comment>
  </data>
</root>

AppResources.en.resx
<root>
  ・
  ・途中省略
  ・
  <data name="PageTitle" xml:space="preserve">
    <value>Page Title</value>
    <comment>title description</comment>
  </data>
</root>



3.カレントカルチャの取得

DependencyServiceでカレントカルチャ(現在設定されている言語)を取得する機能を実装します。
少し記事が長くなりましたので、次回の記事に転載いたします。



4.追加クラスの実装

カレントカルチャーに基づく翻訳文字列を取得する為の2つのクラスファイルを追加します。

PlatformCulture.cs
using System;
namespace AppName.Library.Globalization
{
    public class PlatformCulture
    {
        public PlatformCulture(string platformCultureString)
        {
            if (String.IsNullOrEmpty(platformCultureString))
            {
                throw new ArgumentException("Expected culture identifier", "platformCultureString"); // in C# 6 use nameof(platformCultureString)
            }
            PlatformString = platformCultureString.Replace("_", "-"); // .NET expects dash, not underscore
            var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal);
            if (dashIndex > 0)
            {
                var parts = PlatformString.Split('-');
                LanguageCode = parts[0];
                LocaleCode = parts[1];
            }
            else
            {
                LanguageCode = PlatformString;
                LocaleCode = "";
            }
        }
        public string PlatformString { get; private set; }
        public string LanguageCode { get; private set; }
        public string LocaleCode { get; private set; }
        public override string ToString()
        {
            return PlatformString;
        }
    }
}

TranslateExtension.cs
using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using AppName.Services;
namespace AppName.Library.Globalization
{
    // You exclude the 'Extension' suffix when using in Xaml markup
    [ContentProperty("Text")]
    public class TranslateExtension : IMarkupExtension
    {
        private static CultureInfo _ci = null;
        private const string ResourceId = "AppName.Resources.AppResources";

        public TranslateExtension()
        {
            if (Device.RuntimePlatform == Device.iOS ||
Device.RuntimePlatform == Device.Android)
            {
if (_ci == null)
{
                _ci = DependencyService.Get<ILocalizeService>().GetCurrentCultureInfo();
}
            }
        }

        public string Text { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Text == null)
                return "";

            ResourceManager resmgr = new ResourceManager(ResourceId,
                                typeof(TranslateExtension).GetTypeInfo().Assembly);

            var translation = resmgr.GetString(Text, _ci);

            if (translation == null)
            {
#if DEBUG
                throw new ArgumentException(
                    String.Format("Key '{0}' was not found in resources '{1}' for culture '{2}'.", Text, ResourceId, _ci.Name),
                    "Text");
#else
                translation = Text; // HACK: returns the key, which GETS DISPLAYED TO THE USER
#endif
            }
            return translation;
        }
    }
}



5.iOSの対応

iOSではInfo.plistに多言語化対応を明記する必要があります。
また、Info.plist内に記載されている文字列も多言語化が必要かと考えます。
次の記事「Info.plist内の文字列を多言語化する方法」にてご紹介しておりますのでご参考ください。



6.使用方法

XamlからでもC#からでもどちらでも呼び出しが可能です。

TestPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:i18n="clr-namespace:AppName.Library.Globalization;assembly=AppName"
             x:Class="AppName.Views.TestPage"
             NavigationPage.TitleIcon="icon.png">
    <Label x:Name="PageTitle" Text="{i18n:TranslateExtension Text=PageTitle}" />
<ContentPage>

TestPage.xaml.cs
public partial class TestPage : ContentPage
{
    public TestPage() : base()
    {
        Title = AppResources.PageTitle;
    }
}


AndroidプロジェクトやiOSプロジェクトから呼び出したい場合は、まずPCLプロジェクトに共通の呼び出し関数を用意します。
Common.cs
public static class Common
{
    public static string GetTranslateString(string key)
    {
        return AppResources.ResourceManager.GetString(key);
    }
}


AndroidプロジェクトまたはiOSプロジェクトから以下のように呼び出します。
string title = Common.GetTranslateString("PageTitle");





最後までお読みいただきありがとうございます。
当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
http://itblogdsi.blog.fc2.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

カテゴリ別記事一覧

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語・データベース】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
Oracle10g SQLServer2008R2 SQLAnywhere8/11/16
ActiveReport CrystalReport ReportNet(IBM)
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。