Device Class
Xamarin.Forms 平台功能
包括:平台特定内容(android、ios、uwp)和 平台功能(设备类、本机窗体、本机视图)
Device Class
Device类包含许多属性和方法,以帮助开发人员基于每个平台自定义布局和功能。
除了以特定硬件类型和大小为目标代码的方法和属性之外,Device类还包括可用于与来自后台线程的UI控件进行交互的方法。 有关更多信息,请参见从后台线程与UI交互。
提供平台特定的值
在Xamarin.Forms 2.3.4之前,可以通过检查Device.OS属性并将其与TargetPlatform.iOS,TargetPlatform.Android,TargetPlatform.WinPhone和TargetPlatform.Windows枚举值进行比较来获得运行该应用程序的平台。 类似地,可以使用Device.OnPlatform重载之一为控件(在xaml中)提供特定于平台的值。
但是,从Xamarin.Forms 2.3.4开始,这些API已被弃用和替换,Device类现在包含标识平台的公共字符串常量-Device.iOS,Device.Android,Device.WinPhone(不建议使用),Device.WinRT(不建议使用),Device.UWP和Device.macOS。 同样,Device.OnPlatform重载已被OnPlatform和On(xaml中使用) 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);
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属性可以接受单个字符串值,或多个逗号分隔的字符串值。
注:在On类中提供不正确的Platform属性值不会导致错误。 相反,将在不应用特定于平台的值的情况下执行代码。
或者,可以在XAML中使用OnPlatform标记扩展名,以基于每个平台自定义UI外观。 有关更多信息,请参见OnPlatform标记扩展。
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 });
如果计时器内的代码与用户界面交互(例如设置标签的文本或显示警报),则应在BeginInvokeOnMainThread表达式内进行操作(请参见下文)。
注:System.Timers.Timer和System.Threading.Timer类是.NET Standard替代使用Xamarin.Form.Device.StartTimer方法的类。
Interact with the UI from background threads
通过后台线程与UI进行交互
大多数操作系统(包括iOS,Android和通用Windows平台)对涉及用户界面的代码使用单线程模型,该线程通常称为主线程或UI线程,该模型的结果是,所有访问用户界面元素的代码都必须在应用程序的主线程上运行。
应用程序有时会使用后台线程来执行可能长时间运行的操作,例如从Web服务检索数据,如果在后台线程上运行的代码需要访问用户界面元素,则必须在主线程上运行该代码。
Device类包含以下静态方法,可用于与后台线程中的用户界面元素进行交互:
Method | Arguments | Returns | Purpose |
---|---|---|---|
BeginInvokeOnMainThread |
Action |
void |
Invokes an Action on the main thread, and doesn't wait for it to complete. |
InvokeOnMainThreadAsync<T> |
Func<T> |
Task<T> |
Invokes a Func<T> on the main thread, and waits for it to complete. |
InvokeOnMainThreadAsync |
Action |
Task |
Invokes an Action on the main thread, and waits for it to complete. |
InvokeOnMainThreadAsync<T> |
Func<Task<T>> |
Task<T> |
Invokes a Func<Task<T>> on the main thread, and waits for it to complete. |
InvokeOnMainThreadAsync |
Func<Task> |
Task |
Invokes a Func<Task> on the main thread, and waits for it to complete. |
GetMainThreadSynchronizationContextAsync |
Task<SynchronizationContext> |
Returns the SynchronizationContext for the main thread. |
以下代码显示了使用BeginInvokeOnMainThread方法的示例:
Device.BeginInvokeOnMainThread (() => { // interact with UI elements });