右から左へのローカライズ

右から左へのローカライズでは、Xamarin.Forms アプリケーションに、右から左へのフロー方向のサポートが追加されます。

Note

右から左へのローカライズには、iOS 9 以上、および Android の API 17 以上を使用する必要があります。

フロー方向とは、ページ上の UI 要素を視覚でスキャンしていく方向のことです。 アラビア語やヘブライ語などの一部の言語では、UI 要素が右から左へのフロー方向で配置される必要があります。 これは、VisualElement.FlowDirection プロパティを設定することで実現できます。 このプロパティでは、レイアウトを制御する任意の親要素内での UI 要素のフロー方向が取得または設定され、次のいずれかの FlowDirection 列挙値に設定される必要があります。

要素の FlowDirection プロパティを RightToLeft に設定すると、一般的に配置が右に、読む順が右から左に、コントロールのレイアウトが右から左に設定されます。

右から左へのフロー方向を持つアラビア語の TodoItemPage

ヒント

初期レイアウトでは FlowDirection プロパティのみを設定する必要があります。 実行時にこの値を変更すると、パフォーマンスに影響を与える負荷の高いレイアウト プロセスが発生します。

親のない要素の FlowDirection プロパティの既定値は LeftToRight ですが、親のある要素の FlowDirection の既定値は MatchParent になります。 そのため、要素ではビジュアル ツリー内の親から FlowDirection プロパティ値を継承し、任意の要素でその親から取得した値をオーバーライドできます。

ヒント

右から左方向の言語用にアプリをローカライズする場合、ページ上またはルート レイアウトで FlowDirection プロパティを設定します。 これにより、そのフロー方向に適切に対応して、ページ (ルート レイアウト) 内に含まれるすべての要素が設定されます。

デバイスのフロー方向を優先する

選択した言語とリージョンに基づいてデバイスのフロー方向を優先するには、開発者が明示的に選択する必要があり、自動的に行われることはありません。 これは、ページ (ルート レイアウト) の FlowDirection プロパティを static Device.FlowDirection 値に設定することで実現できます。

<ContentPage ... FlowDirection="{x:Static Device.FlowDirection}"> />
this.FlowDirection = Device.FlowDirection;

その後、既定では、ページ (ルート レイアウト) の子要素はすべて、Device.FlowDirection 値を継承します。

プラットフォームの設定

特定のプラットフォームの設定では、右から左のロケールを有効にする必要があります。

iOS

Info.plistCFBundleLocalizations キー用の配列項目に対してサポートされる言語として、必要な右から左のロケールを追加する必要があります。 次の例では、CFBundleLocalizations キーの配列に追加されているアラビア語を示しています。

<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>ar</string>
</array>

Info.plist のサポートされる言語

詳細については、「iOS でのローカライズの基本事項」を参照してください。

右から左へのローカライズは、デバイスまたはシミュレーター上の言語とリージョンを Info.plist で指定された右から左のロケールに変更することによって、テストできます。

警告

iOS で言語とリージョンを右から左のロケールに変更するときに、そのロケールに必要なリソースを含めていない場合、任意の DatePicker ビューで例外がスローされることに注意してください。 たとえば、DatePicker を含むアラビア語のアプリをテストする場合、[iOS ビルド] ウィンドウの [国際化] セクションに [mideast] が選択されていることを確認します。

Android

アプリの AndroidManifest.xml ファイルは更新されているため、<uses-sdk> ノードで android:minSdkVersion 属性は 17 に設定され、<application> ノードで android:supportsRtl 属性は true に設定されます。

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <uses-sdk android:minSdkVersion="17" ... />
    <application ... android:supportsRtl="true">
    </application>
</manifest>

その後、デバイスまたはエミュレーターで右から左方向の言語を使用するように変更するか、または [設定] > [開発者向けオプション][Force RTL layout direction]\(RTL レイアウト方向を使用\) をオンにすることで、右から左へのローカライズをテストできます。

ユニバーサル Windows プラットフォーム (UWP)

必要な言語リソースは、Package.appxmanifest ファイルの <Resources> ノードで指定する必要があります。 次の例では、<Resources> ノードに追加されているアラビア語を示します。

<Resources>
    <Resource Language="x-generate"/>
    <Resource Language="en" />
    <Resource Language="ar" />
</Resources>

さらに、UWP では、アプリの既定のカルチャが明示的に .NET Standard ライブラリで定義されている必要があります。 これは、AssemblyInfo.cs (別のクラス) の NeutralResourcesLanguage 属性を既定のカルチャに設定することで実現できます。

using System.Resources;

[assembly: NeutralResourcesLanguage("en")]

右から左へのローカライズは、デバイス上の言語とリージョンを適切な右から左のロケールに変更するこでテストできます。

制限事項

Xamarin.Forms での右から左へのローカライズには、現在いくつかの制限があります。

  • NavigationPage のボタンの場所、ツール バー項目の場所、および切り替えアニメーションは、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。
  • CarouselPage のスワイプ方向は反転されません。
  • Image のビジュアル コンテンツは反転されません。
  • WebView のコンテンツでは FlowDirection プロパティを優先しません。
  • テキストの配置を制御するには、TextDirection プロパティを追加する必要があります。

iOS

  • Stepper の向きは、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。
  • EntryCell のテキストの配置は、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。
  • ContextActions のジェスチャと配置は反転されません。

Android

  • SearchBar の向きは、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。
  • ContextActions の配置は、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。

UWP

  • Editor のテキストの配置は、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。
  • FlowDirection プロパティは子の FlyoutPage に継承されません。
  • ContextActions のテキストの配置は、FlowDirection プロパティではなく、デバイスのロケールによって制御されます。

右から左へのレイアウトを強制する

Xamarin.iOS および Xamarin.Android アプリケーションには、それぞれのプラットフォーム プロジェクトを変更することにより、デバイスの設定に関係なく、常に右から左へのレイアウトを使用するように強制することができます。

iOS

Xamarin.iOS アプリケーションには、次のように AppDelegate クラスを変更することにより、常に右から左へのレイアウトを使用するように強制することができます。

  1. IntPtr_objc_msgSend 関数を AppDelegate クラスの最初の行として宣言します。

    [System.Runtime.InteropServices.DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
    internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, UISemanticContentAttribute arg1);
    
  2. FinshedLaunching メソッドから戻る前に、FinishedLaunching メソッドから IntPtr_objc_msgSend 関数を呼び出します。

    bool result = base.FinishedLaunching(app, options);
    
    ObjCRuntime.Selector selector = new ObjCRuntime.Selector("setSemanticContentAttribute:");
    IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceRightToLeft);
    
    return result;
    

この方法は、常に右から左へのレイアウトを必要とするアプリケーションの場合に役立ち、FlowDirection プロパティを設定する必要がなくなります。

IntrPtr_objc_msgSend メソッドの詳細については、「Xamarin. iOS の Objective-C セレクター」を参照してください。

Android

Xamarin.Android アプリケーションには、次の行を含むように MainActivity クラスを変更することで、常に右から左へのレイアウトを使用するように強制することができます。

Window.DecorView.LayoutDirection = LayoutDirection.Rtl;

Note

この方法を使用するには、右から左へのレイアウトをサポートするようにアプリケーションをセットアップする必要があります。 詳細については、Android プラットフォームのセットアップに関するページを参照してください。

この方法は、常に右から左へのレイアウトを必要とするアプリケーションの場合に役立ち、大部分のコントロールに対して FlowDirection プロパティを設定する必要がなくなります。 ただし、CollectionView などの一部のコントロールには、LayoutDirection プロパティを考慮するのでなく、引き続き FlowDirection プロパティを設定する必要があります。

Xamarin.University での右から左方向の言語のサポート

Xamarin.Forms 3.0 での右から左方向へのサポートに関するビデオ