Device Class

PDF for offline use
Sample Code:
Related APIs:

Let us know how you feel about this

Translation Quality


0/250

last updated: 2017-04

The Device class contains a number of properties and methods to help developers customize layout and functionality on a per-platform basis.

In addition to methods and properties to target code at specific hardware types and sizes, the Device class includes the BeginInvokeOnMainThread method which should be used when interacting with UI controls from background threads.

Providing Platform-Specific Values

Prior to Xamarin.Forms 2.3.4, the platform the application was running on could be obtained by examining the Device.OS property and comparing it to the TargetPlatform.iOS, TargetPlatform.Android, TargetPlatform.WinPhone, and TargetPlatform.Windows enumeration values. Similarly, one of the Device.OnPlatform overloads could be used to provide platform-specific values to a control.

However, Xamarin.Forms 2.3.4 has deprecated and replaced these APIs. For example, the Device class now contains public string constants that identify platforms – Device.iOS, Device.Android, Device.WinPhone, and Device.Windows. Similarly, the Device.OnPlatform overloads have been replaced with the OnPlatform and On APIs.

In C#, platform-specific values can be provided by creating a switch statement on the Device.RuntimePlatform property, and then providing case statements for the required platforms:

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

The OnPlatform and On classes provide the same functionality in XAML:

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

The OnPlatform class is a generic class and so must be instantiated with an x:TypeArguments attribute that matches the target type. In the On class, the Platform attribute can accept a single string value, or multiple comma-delimited string values. In addition, note that the above XAML can be simplified to become:

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

Providing an incorrect Platform attribute value in the On class will not result in an error. Instead, the code will execute without the platform-specific value being applied.

Device.Idiom

The Device.Idiom can be used to alter layouts or functionality depending on whether the device is a phone or a tablet. The TargetIdiom enumeration contains the following values:

  • Phone – iPhone, iPod touch, Windows Phone, Android devices narrower than 600 dips^
  • Tablet – iPad, Windows 8.1 computers, Android devices wider than 600 dips^
  • Desktop – only returned in UWP apps on Windows 10 desktop computers (returns Phone on on mobile Windows devices)
  • Unsupported – unused

^ dips is not necessarily the physical pixel count

Idiom is especially useful for building layouts that take advantage of larger screens, like this:

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

Device.Styles

The Styles property contains built-in style definitions that can be applied to some controls' (such as Label) Style property. The available styles are:

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

Device.GetNamedSize

GetNamedSize can be used when setting FontSize in C# code:

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.OpenUri

The OpenUri method can be used to trigger operations on the underlying platform, such as open a URL in the native web browser (Safari on iOS or Internet on Android).

Device.OpenUri(new Uri("https://evolve.xamarin.com/"));

The WebView sample includes an example using OpenUri to open URLs and also trigger phone calls.

The Maps sample also uses Device.OpenUri to display maps and directions using the native Maps apps on iOS and Android.

Device.StartTimer

The Device class also has a StartTimer method which provides a simple way to trigger time-dependent tasks that works in Xamarin.Forms common code (including PCLs). Pass a TimeSpan to set the interval and return true to keep the timer running or false to stop it after the current invocation.

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

If the code inside the timer interacts with the user-interface (such as setting the text of a Label or displaying an alert) it should be done inside a BeginInvokeOnMainThread expression (see below).

Device.BeginInvokeOnMainThread

User interface elements should never be accessed by background threads, such as code running in a timer or a completion handler for asynchronous operations like web requests. Any background code that needs to update the user interface should be wrapped inside BeginInvokeOnMainThread. This is the equivalent of InvokeOnMainThread on iOS, RunOnUiThread on Android, and Dispatcher.BeginInvoke on Windows Phone.

The Xamarin.Forms code is:

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

Note that methods using async/await do not need to use BeginInvokeOnMainThread if they are running from the main UI thread.

Summary

The Xamarin.Forms Device class allows fine-grained control over functionality and layouts on a per-platform basis - even in common code (either PCL or Shared Projects).

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.