根據 Xamarin.Essentials 官方文件中指出:Xamarin.Essentials 跨平台應用程式開發介面的開發人員提供他們的行動應用程式。透過 Xamarin.Essentials 的套件幫忙,可以將這些功能整合到您的應用程式:加速計 應用程式資訊 電池 剪貼簿 指南針 資料傳輸 裝置顯示資訊 裝置資訊 電子郵件 檔案系統的協助程式 手電筒 地理編碼 地理位置 迴轉儀 磁力計 開啟瀏覽器 電話撥號員 喜好設定 螢幕鎖定 安全儲存體 SMS 文字轉換語音 追蹤版本 震動。
我們現在來體驗關於 Device Display Information 裝置顯示的資訊 這項功能,因此,可以參考底下的專案範例,該專案範例
建立測試專案
- 首先,我們先使用 Prism Template Pack 擴充功能所提供的專案樣板,建立起一個 Xamarin.Forms 專案,在這裡我們僅選擇 Android / iOS / UWP 類型的專案;接著,我們需要把 PropertyChanged.Fody NuGet 套件安裝到 .NET Standard 專案類別庫內,並且安裝 FodyWeavers.xml 檔案。
- 緊接著,我們要開始安裝 Xamarin.Essentials NuGet 套件到所有的專案內,在這裡,請使用滑鼠右擊方案節點,選擇 管理方案的 NuGet 套件 選項
- 請在 NuGet - 解決方案 的視窗中,輸入要搜尋的套件名稱 : Xamarin.Essentials並且,請勾選 包括搶鮮版 的文字檢查盒,並且安裝這個套件;我寫這篇文章的時候, Xamarin.Essentials 的最新版本為 0.7.0.17 版本,因此,我們安裝這個版本。
- 當 Xamarin.Essentials 套件安裝完成之後,您將會發現到在 Visual Studio 2017 的錯誤視窗中,出現了底下錯誤訊息
偵測到 Xamarin.Android.Support.Compat 的版本衝突。請直接從專案參考套件,以解決此問題。
XFESFileSystem.Android -> Xamarin.Essentials 0.7.0.17-preview -> Xamarin.Android.Support.CustomTabs 27.0.2 -> Xamarin.Android.Support.Compat (= 27.0.2)
XFESFileSystem.Android -> Xamarin.Android.Support.Design 25.4.0.2 -> Xamarin.Android.Support.Compat (= 25.4.0.2).
- 這個時候您可以參考 Xamarin.Essentials 體驗 1 : File System Helpers 檔案系統存取 文章中的解決辦法完成之後,Android 專案下的 .csproj 檔案,請搜尋這個關鍵字 PackageReference Include="Xamarin.Essentials", 此時,您將會看到底下的內容,安裝了 Xamarin.Android.Support.CustomTabs NuGet 套件,並且都升級到 27.0.2.1 版本當然,最快的方式,就是使用 Visual Studio Code 工具,開啟 Android 專案下的 .csproj 檔案,值些修改成為底下內容,儲存後回到 Visual Studio 2017 下,緊接著重新載入這個 .csproj 檔案,就可以進行 Android 專案的編譯動作囉。
<PackageReference Include="Xamarin.Essentials" Version="0.7.0.17-preview"/>
<PackageReference Include="Xamarin.Android.Support.CustomTabs" Version="27.0.2.1"/>
<PackageReference Include="Xamarin.Android.Support.Design" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v4" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.CardView" Version="27.0.2.1" />
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="27.0.2.1" />
- 如此,最初產生的錯誤訊息便會消失了。
- 我們將開始要進行 View ViewModel Model 的設計了,首先,我們開啟 MainPage.xaml 這個檔案,底下是我們測試的頁面 XAML 語法在這裡,我們將會增加一個按鈕,用來取得最新的螢幕裝置的顯示資訊
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XFESDeviceDisplay.Views.MainPage"
Title="Device Display Information 裝置顯示的資訊">
<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="Welcome to Xamarin Forms and Prism!" />
<Label Text="{Binding Orientation, StringFormat='Orientation : {0}'}" FontSize="20"/>
<Label Text="{Binding Rotation, StringFormat='Rotation : {0}'}" FontSize="20"/>
<Label Text="{Binding Width, StringFormat='Width : {0}'}" FontSize="20"/>
<Label Text="{Binding Height, StringFormat='Height : {0}'}" FontSize="20"/>
<Label Text="{Binding Density, StringFormat='Density : {0}'}" FontSize="20"/>
<Button Text="Refresh" Command="{Binding RefreshCommand}"/>
</StackLayout>
</ContentPage>
- 請打開 MainPageViewModel.cs 這個檔案在這個檔案中,我們將會在 OnNavigatedTo 事件中,使用 DeviceDisplay 類別各個屬性,將其值取出來,設定要綁定到頁面的屬性物件中。不過, DeviceDisplay 類別內有個 ScreenMetricsChanaged 事件,將會於螢幕顯示屬性值有變化的時候,便會觸發這個事件,我們將會於 OnNavigatedTo 事件中綁定這個事件到 Lambda 委派方法內,而這個方法會把該事件傳入的參數之 ScreenMetrics 內容,重新顯示到螢幕上。
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace XFESDeviceDisplay.ViewModels
{
using System.ComponentModel;
using Prism.Events;
using Prism.Navigation;
using Prism.Services;
using Xamarin.Essentials;
public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
{
public event PropertyChangedEventHandler PropertyChanged;
public string Orientation { get; set; }
public string Rotation { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double Density { get; set; }
public DelegateCommand RefreshCommand { get; set; }
private readonly INavigationService _navigationService;
public MainPageViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
RefreshCommand = new DelegateCommand(() =>
{
Refresh(DeviceDisplay.ScreenMetrics);
});
}
public void OnNavigatedFrom(NavigationParameters parameters)
{
}
public void OnNavigatingTo(NavigationParameters parameters)
{
}
public void OnNavigatedTo(NavigationParameters parameters)
{
Refresh(DeviceDisplay.ScreenMetrics);
DeviceDisplay.ScreenMetricsChanaged += (x) =>
{
Refresh(x.Metrics);
};
}
public void Refresh(ScreenMetrics screenMetrics)
{
Orientation = screenMetrics.Orientation.ToString();
Rotation = screenMetrics.Rotation.ToString();
Width = screenMetrics.Width;
Height = screenMetrics.Height;
Density = screenMetrics.Density;
}
}
}
- 根據官方文件上的說明
- Landscape 2 Screen is in landscape.
- Portrait 1 Screen is in portrait.
- Unknown 0 Unknown screen orientation.
- Rotation0 0 Rotated 0 degrees.
- Rotation180 2 Rotated 180 degrees.
- Rotation270 3 Rotated 270 degrees.
- Rotation90 1 Rotated 90 degrees.
- Android 平台執行結果這是一開始執行的螢幕截圖現在,我們將螢幕轉個九十度,這個時候, DeviceDisplay.ScreenMetricsChanaged 事件將會被觸發,並且會把最新螢幕顯示裝套重新顯示在螢幕頁面上;不過,事與願違,似乎這個事件所傳入的引數值,並不是這個時候螢幕的最新顯示狀態值。現在,讓我們按下 Refresh 按鈕後,您將會看到現在最新的螢幕顯示狀態值了。
- UWP 平台執行結果這是一開始執行的螢幕截圖,在我的 Windows 10 電腦環境中,我有雙螢幕,現在看到的是我主螢幕的顯示資訊。現在,我們將該視窗拖拉到另外一個螢幕下,這個時候, 我們可以看到 DeviceDisplay.ScreenMetricsChanaged 事件將會被觸發,並且會把最新螢幕顯示裝套重新顯示在螢幕頁面上。這樣的機制在 UWP 環境中是運作正常的。