Xamarin.Forms Device クラス

Device クラスには、開発者がプラットフォームごとにレイアウトと機能をカスタマイズするのに役立つさまざまなプロパティとメソッドが含まれています。

特定のハードウェアの種類とサイズをコードの対象とするメソッドとプロパティに加えて、Device クラスには、バックグラウンド スレッドから UI コントロールを操作するために使用できるメソッドが含まれています。 詳細については、バックグラウンド スレッドからの UI の操作に関する記事を参照してください。

プラットフォーム固有の値を指定する

Xamarin.Forms 2.3.4 より前は、アプリケーションが実行されているプラットフォームを取得するには、Device.OS プロパティを調べて、それを TargetPlatform.iOSTargetPlatform.AndroidTargetPlatform.WinPhoneTargetPlatform.Windows 列挙値と比較しました。 同様に、Device.OnPlatform オーバーロードのいずれかを使用して、プラットフォーム固有の値をコントロールに提供できました。

ただし、Xamarin.Forms 2.3.4 以降、これらの API は非推奨となり、置き換えられました。 Device クラスには、プラットフォームを識別するパブリック文字列定数 (Device.iOSDevice.AndroidDevice.WinPhone ( 非推奨)、Device.WinRT (非推奨)、Device.UWP および Device.macOS) が含まれるようになりました。 同様に、Device.OnPlatform オーバーロードは、OnPlatformOn API に置き換えられました。

C# では、Device.RuntimePlatform プロパティに switch ステートメントを作成し、必要なプラットフォームの case ステートメントを指定することで、プラットフォーム固有の値を指定できます。

double top;
switch (Device.RuntimePlatform)
{
  case Device.iOS:
    top = 20;
    break;
  case Device.Android:
  case Device.UWP:
  default:
    top = 0;
    break;
}
layout.Margin = new Thickness(5, top, 5, 0);

OnPlatform クラスと On クラスは、XAML で同じ機能を提供します。

<StackLayout>
  <StackLayout.Margin>
    <OnPlatform x:TypeArguments="Thickness">
      <On Platform="iOS" Value="0,20,0,0" />
      <On Platform="Android, UWP" Value="0,0,0,0" />
    </OnPlatform>
  </StackLayout.Margin>
  ...
</StackLayout>

OnPlatform クラスはジェネリック クラスであり、対象の型と一致する x:TypeArguments 属性を使用してインスタンス化する必要があります。 On クラスで、Platform 属性は 1 つのstring値または複数のコンマ区切りstring 値を受け取ることができます。

重要

On クラスで不適切な Platform 属性値を指定しても、エラーは発生しません。 代わりに、コードはプラットフォーム固有の値が適用されない状態で実行されます。

あるいは、プラットフォームごとに UI の外観をカスタマイズするために、OnPlatform マークアップ拡張を XAML で使用できます。 詳細については、「OnPlatform マークアップ拡張」 を参照してください。

Device.Idiom

Device.Idiom プロパティを使用すると、アプリケーションが実行されているデバイスに応じてレイアウトや機能を変更できます。 TargetIdiom 列挙体には次の値が含まれます。

  • Phone – iPhone、iPod touch、600 dips より狭い Android デバイス^
  • Tablet – iPad、Windows デバイス、600 dips を超える幅の Android デバイス^
  • Desktop – Windows 10 デスクトップ コンピューター上の UWP アプリ でのみ返されます (Continuum シナリオを含むモバイル Windows デバイスでは Phone が返されます)
  • TV – Tizen TV デバイス
  • Watch – Tizen ウォッチ デバイス
  • Unsupported – 未使用

^ dips は必ずしも物理ピクセル数であるとは限りません

Idiom プロパティは、次のような大きな画面を利用するレイアウトを構築する場合に特に便利です。

if (Device.Idiom == TargetIdiom.Phone) {
    // layout views vertically
} else {
    // layout views horizontally for a larger display (tablet or desktop)
}

OnIdiomクラスは、XAML で同じ機能を提供します。

<StackLayout>
    <StackLayout.Margin>
        <OnIdiom x:TypeArguments="Thickness">
            <OnIdiom.Phone>0,20,0,0</OnIdiom.Phone>
            <OnIdiom.Tablet>0,40,0,0</OnIdiom.Tablet>
            <OnIdiom.Desktop>0,60,0,0</OnIdiom.Desktop>
        </OnIdiom>
    </StackLayout.Margin>
    ...
</StackLayout>

OnIdiom クラスはジェネリック クラスであり、対象の型と一致する x:TypeArguments 属性を使用してインスタンス化する必要があります。

あるいは、OnIdiom マークアップ拡張を XAMLで使用して、アプリケーションが実行されているデバイスのイディオムに基づいて UI の外観をカスタマイズできます。 詳細については、「OnIdiom マークアップ拡張」を参照してください。

Device.FlowDirection

Device.FlowDirection 値は、デバイスで使用されている現在のフロー方向を表す FlowDirection 列挙値を取得します。 フロー方向とは、ページ上の UI 要素を視覚でスキャンしていく方向のことです。 列挙値は、次のとおりです。

XAML では、x:Static マークアップ拡張を使用して Device.FlowDirection 値を取得できます。

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

これに相当する C# コードを次に示します。

this.FlowDirection = Device.FlowDirection;

フローの方向について詳しくは、「右から左へのローカライズ」をご覧ください。

Device.Styles

Styles プロパティには、一部のコントロール (たとえば Label) Style プロパティに適用できる組み込みのスタイル定義が含まれています。 使用できるスタイルは次のとおりです。

  • BodyStyle
  • CaptionStyle
  • ListItemDetailTextStyle
  • ListItemTextStyle
  • SubtitleStyle
  • TitleStyle

Device.GetNamedSize

GetNamedSize は、C# コードで FontSize を設定するときに使用できます。

myLabel.FontSize = Device.GetNamedSize (NamedSize.Small, myLabel);
someLabel.FontSize = Device.OnPlatform (
      24,         // hardcoded size
      Device.GetNamedSize (NamedSize.Medium, someLabel),
      Device.GetNamedSize (NamedSize.Large, someLabel)
);

Device.GetNamedColor

Xamarin.Forms 4.6 では、名前付きの色のサポートが導入されています。 名前付きの色とは、デバイスでアクティブなシステム モード (ライトやダークなど) に応じて異なる値を持つ色です。 Android では、名前付きの色は R.Color クラスを介してアクセスされます。 iOS では、名前付きの色はシステム カラーと呼ばれます。 ユニバーサル Windows プラットフォームでは、名前付きの色は XAML テーマ リソースと呼ばれます。

GetNamedColor メソッドを使用して、Android、iOS、UWP で名前付きの色を取得できます。 このメソッドは string 引数を受け取り、Color を返します。

// Retrieve an Android named color
Color color = Device.GetNamedColor(NamedPlatformColor.HoloBlueBright);

カラー名が見つからない場合、またはサポートされていないプラットフォームで GetNamedColor が呼び出された場合は、Color.Default が返されます。

Note

GetNamedColor メソッドはプラットフォームに固有の Color を返すため、通常は Device.RuntimePlatform プロパティと組み合わせて使用する必要があります。

NamedPlatformColor クラスには、Android、iOS、UWP の名前付きの色を定義する定数が含まれています。

Android iOS macOS UWP
BackgroundDark Label AlternateSelectedControlTextColor SystemAltHighColor
BackgroundLight Link ControlAccent SystemAltLowColor
Black OpaqueSeparator ControlBackgroundColor SystemAltMediumColor
DarkerGray PlaceholderText ControlColor SystemAltMediumHighColor
HoloBlueBright QuaternaryLabel DisabledControlTextColor SystemAltMediumLowColor
HoloBlueDark SecondaryLabel FindHighlightColor SystemBaseHighColor
HoloBlueLight Separator GridColor SystemBaseLowColor
HoloGreenDark SystemBlue HeaderTextColor SystemBaseMediumColor
HoloGreenLight SystemGray HighlightColor SystemBaseMediumHighColor
HoloOrangeDark SystemGray2 KeyboardFocusIndicatorColor SystemBaseMediumLowColor
HoloOrangeLight SystemGray3 Label SystemChromeAltLowColor
HoloPurple SystemGray4 LabelColor SystemChromeBlackHighColor
HoloRedDark SystemGray5 Link SystemChromeBlackLowColor
HoloRedLight SystemGray6 LinkColor SystemChromeBlackMediumColor
TabIndicatorText SystemGreen PlaceholderText SystemChromeBlackMediumLowColor
Transparent SystemIndigo PlaceholderTextColor SystemChromeDisabledHighColor
White SystemOrange QuaternaryLabel SystemChromeDisabledLowColor
WidgetEditTextDark SystemPink QuaternaryLabelColor SystemChromeHighColor
SystemPurple SecondaryLabel SystemChromeLowColor
SystemRed SecondaryLabelColor SystemChromeMediumColor
SystemTeal SelectedContentBackgroundColor SystemChromeMediumLowColor
SystemYellow SelectedControlColor SystemChromeWhiteColor
TertiaryLabel SelectedControlTextColor SystemListLowColor
SelectedMenuItemTextColor SystemListMediumColor
SelectedTextBackgroundColor
SelectedTextColor
Separator
SeparatorColor
ShadowColor
SystemBlue
SystemGray
SystemGreen
SystemIndigo
SystemOrange
SystemPink
SystemPurple
SystemRed
SystemTeal
SystemYellow
TertiaryLabel
TertiaryLabelColor
TextBackgroundColor
TextColor
UnderPageBackgroundColor
UnemphasizedSelectedContentBackgroundColor
UnemphasizedSelectedTextBackgroundColor
UnemphasizedSelectedTextColor
WindowBackgroundColor
WindowFrameTextColor

Device.StartTimer

Device クラスには、 .NET Standard ライブラリを含む Xamarin.Forms の一般的なコードで動作する時間依存タスクをトリガーする簡単な方法を提供する StartTimer メソッドもあります。 TimeSpan を渡して間隔を設定し、タイマーを実行したままにする true を返すか、現在の呼び出し後に停止するための false を返します。

Device.StartTimer (new TimeSpan (0, 0, 60), () =>
{
    // do something every 60 seconds
    return true; // runs again, or false to stop
});

タイマー内のコードがユーザー インターフェイスと対話する場合 (Label のテキストの設定やアラートの表示など)、BeginInvokeOnMainThread 式内で行う必要があります (以下を参照)。

Note

System.Timers.TimerSystem.Threading.Timer クラスは、Device.StartTimer メソッドの使用に対する .NET Standard での代替手段です。

バックグラウンド スレッドから UI を操作する

iOS、Android、ユニバーサル Windows プラットフォームなどのほとんどのオペレーティング システムでは、ユーザー インターフェイスに関連するコードについてシングル スレッド モデルが使用されています。 多くの場合、このスレッドは "メイン スレッド" または "UI スレッド" と呼ばれます。 このモデルの結果、ユーザー インターフェイス要素にアクセスするすべてのコードはアプリケーションのメイン スレッドで実行する必要があります。

アプリケーションでは、Web サービスからのデータの取得など、実行時間が長くなる可能性がある操作をバックグラウンド スレッドを使用して実行することがあります。 バックグラウンド スレッドで実行しているコードでユーザー インターフェイス要素にアクセスする必要がある場合は、そのコードをメイン スレッドで実行する必要があります。

Device クラスには、バックグラウンド スレッドからユーザー インターフェイス要素とやりとりするために使用できる static メソッドが含まれています。

メソッド 引数 戻り値 目的
BeginInvokeOnMainThread Action void メイン スレッドで Action を呼び出し、それが完了するのを待機しません。
InvokeOnMainThreadAsync<T> Func<T> Task<T> メイン スレッド上で Func<T> を呼び出し、それが完了するまで待機します。
InvokeOnMainThreadAsync Action Task メイン スレッド上で Action を呼び出し、それが完了するまで待機します。
InvokeOnMainThreadAsync<T> Func<Task<T>> Task<T> メイン スレッド上で Func<Task<T>> を呼び出し、それが完了するまで待機します。
InvokeOnMainThreadAsync Func<Task> Task メイン スレッド上で Func<Task> を呼び出し、それが完了するまで待機します。
GetMainThreadSynchronizationContextAsync Task<SynchronizationContext> メイン スレッドの SynchronizationContext を返します。

次のコードは、BeginInvokeOnMainThread メソッドの使用例を示しています。

Device.BeginInvokeOnMainThread (() =>
{
    // interact with UI elements
});