Xamarin.Forms Device 类
Device
类包含许多属性和方法,可帮助开发人员在每个平台的基础上自定义布局和功能。
除了面向特定硬件类型和大小的代码的方法和属性之外,Device
类还包括可用于与后台线程中的 UI 控件交互的方法。 有关详细信息,请参阅从后台线程与 UI 交互。
提供特定于平台的值
在 Xamarin.Forms 2.3.4 之前,可以通过检查 Device.OS
属性并将其与 TargetPlatform.iOS
、TargetPlatform.Android
、TargetPlatform.WinPhone
和 TargetPlatform.Windows
枚举值进行比较来获取应用程序运行的平台。 同样,其中一个 Device.OnPlatform
重载可用于向控件提供特定于平台的值。
但是,自 Xamarin.Forms 2.3.4 以来,这些 API 已被弃用并替换。 Device
类现包含公共字符串常量,这些常量用于标识平台 – Device.iOS
、Device.Android
、Device.WinPhone
(已弃用)、Device.WinRT
(已弃用)、Device.UWP
以及 Device.macOS
。 同样,Device.OnPlatform
重载已替换为 OnPlatform
和 On
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
属性可以接受单个 string
值或多个逗号分隔的 string
值。
重要
在 Platform
类中提供不正确的 On
特性值不会导致错误。 相反,代码将执行,而不会应用特定于平台的值。
或者,可以在 XAML 中使用 OnPlatform
标记扩展来自定义每个平台的 UI 外观。 有关详细信息,请参阅 OnPlatform 标记扩展。
Device.Idiom
Device.Idiom
属性可用于根据应用程序正在运行的设备更改布局或功能。 TargetIdiom
枚举包含以下值:
- 手机 – iPhone、iPod touch 和 Android 设备(像素小于 600 dip^)
- 平板电脑 – iPad、Windows 设备和 Android 设备(像素大于 600 dip^)
- 桌面设备 - 仅在 Windows 10 台式计算机上的 UWP 应用中返回(在移动 Windows 设备上返回
Phone
,包括在 Continuum 方案中) - 电视 - Tizen 电视设备
- 手表 - Tizen 手表设备
- 不支持 – 未使用
^ dip 不一定是物理像素计数
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
特性进行实例化。
或者,可以在 XAML 中使用 OnIdiom
标记扩展,以根据运行应用程序的设备的惯用法来自定义 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
。
注意
由于 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
类还有一种 StartTimer
方法,会提供一种简单的方法来触发在 Xamarin.Forms 通用代码中工作的时间相关任务,包括 .NET Standard 库。 传递 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
表达式中完成(请参阅下文)。
注意
System.Timers.Timer
和 System.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
});