Windows 10 開發 - 自適應程式碼



在本章中,我們將演示如何使您的應用程式適應 Windows 10 支援的不同裝置。我們已經瞭解瞭如何適應您的 UI 以及 UWP 應用程式中使用的所有技巧、技術和控制元件。

現在,我們將學習如何適應您的程式碼,因為

  • 應用程式程式碼在所有裝置上並不相同。

  • 使用的 API,特別是針對 Xbox 的 API,在移動裝置上不可用。HoloLens 等裝置也是如此。

Windows Devices

自適應程式碼可以根據條件啟用您的應用程式,並在特定裝置系列和/或特定版本的平臺/擴充套件 API 上執行時執行程式碼。

編寫程式碼

在 Windows 10 中,您可以使用 Visual Studio 使用 C++、C#、Visual Basic 或 JavaScript 來實現 UWP 應用程式。

  • 使用 C# 和 Visual Basic,您可以使用 XAML 進行 UI 設計。

  • 使用 C++,您可以使用 DirectX 而不是 XAML。

  • 對於 JavaScript,您可以使用 HTML 作為您的表示層,它是一個跨平臺的 Web 標準。

Windows Core API 在所有裝置上都以相同的方式執行,其中包含程式碼和 UI 所需的大部分功能。但是,對於針對特定裝置系列的程式碼和 UI,您需要使用自適應程式碼和自適應 UI。

呼叫目標裝置系列未實現的 API -

UI 可以輕鬆適應不同的螢幕,但不同的裝置系列不僅僅具有不同的螢幕尺寸,還有更多差異。

  • 例如,手機有一些硬體按鈕,如後退和攝像頭,這些按鈕在其他裝置(如 PC)上可能不可用。

  • 預設情況下,核心 API 包含適用於所有裝置的大部分功能,但可以透過在您的 UWP 應用程式中引用擴充套件 SDK(就像外部程式集一樣)來使用裝置特定的功能。

要新增應用程式中需要的任何特定擴充套件 SDK,請按照以下步驟操作 -

  • 右鍵單擊引用

  • 選擇“新增引用...”。將開啟以下對話方塊。

Add References Manager
  • 新增擴充套件就像新增專案引用一樣簡單。

  • 現在,您可以從列表中新增任何擴充套件 SDK,其中包含桌面擴充套件、物聯網擴充套件和移動擴充套件等。

桌面和移動擴充套件是兩種最常見的平臺擴充套件 SDK。例如,移動擴充套件啟用了使用硬體攝像頭按鈕所需的 API。

您可以使用Windows.Foundation.Metadata.ApiInformation 類方法檢查裝置功能,如果當前裝置上支援該型別,則該方法返回布林輸出。例如,您可以使用以下程式碼啟用 Windows 應用以使用攝像頭按鈕 -

bool isHardwareButtonsAPIPresent = 
   Windows.Foundation.Metadata.ApiInformation.
   IsTypePresent("Windows.Phone.UI.Inpu t.HardwareButtons");  
		
if (isHardwareButtonsAPIPresent) { 
   Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed; 
} 

只有在裝置上啟用了移動擴充套件 SDK 時,手機攝像頭按鈕程式碼才會執行。類似地,您還可以使用IsEventPresentIsMethodPresentIsPropertyPresent代替IsTypePresent來檢查當前 API 版本中的任何特定事件、方法或屬性,如下所示。

bool isHardwareButtons_CameraPressedAPIPresent = 
   Windows.Foundation.Metadata.ApiInformation.IsEventPresent 
   ("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");

UWP 中的 Win32 API

通用 Windows 平臺 (UWP) 應用程式或 Windows 執行時元件(使用 C++/CX 編寫)可以訪問 Win32 API,這些 API 現在也是 UWP 的一部分。所有 Windows 10 裝置系列都可以透過將應用程式與Windowsapp.lib連結來實現 Win32 API。

Windowsapp.lib是一個“傘形”庫,提供 UWP API 的匯出。連結到Windowsapp.lib將向您的應用新增對所有 Windows 10 裝置系列中存在的dll的依賴項。

讓我們來看一個簡單的示例,其中應用程式同時針對桌面和手機。因此,當應用程式在桌面上執行時,它不會顯示狀態列,但當相同的應用程式在手機上執行時,它將顯示狀態列。

以下是新增不同控制元件的 XAML 程式碼。

<Page 
   x:Class = "UWPAdoptiveCode.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "using:UWPAdoptiveCode" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d">  

   <Page.Background> 
      <SolidColorBrush Color = "Green"/> 
   </Page.Background>
	
   <Page.BottomAppBar> 
      <CommandBar x:Name = "commandBar" > 
         <AppBarButton Icon = "Accept" Label = "appbarbutton"/> 
         <AppBarButton Icon = "Cancel" Label = "appbarbutton"/> 
      </CommandBar> 
   </Page.BottomAppBar>
	
   <Grid Background = "AliceBlue"> 
	
      <VisualStateManager.VisualStateGroups> 
		
         <VisualStateGroup> 
			
            <VisualState> 
               <VisualState.StateTriggers> 
                  <local:DeviceFamilyTrigger DeviceFamily = "Desktop" /> 
               </VisualState.StateTriggers> 
					
               <VisualState.Setters> 
                  <Setter Target = "StatusBarControls.Visibility" 
                     Value = "Collapsed"/> 
               </VisualState.Setters>  
					
            </VisualState> 
				
         </VisualStateGroup> 
			
      </VisualStateManager.VisualStateGroups> 
		
      <StackPanel HorizontalAlignment = "Left" Margin = "75,164,0,0"
         VerticalAlignment = "Top" > 
			
         <RadioButton x:Name = "ShowAppBarRadioButton" Content = "Show AppBar"
            HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch"
            IsChecked = "True" Checked = "RadioButton_Checked"/>
				
         <RadioButton x:Name = "ShowOpaqueAppBarRadioButton" 
            Content = "Show Transparent AppBar" HorizontalAlignment = "Stretch"
            VerticalAlignment = "Stretch" Checked = "RadioButton_Checked"/> 
				
         <RadioButton x:Name = "HideAppBarRadioButton" Content = "Hide AppBar"
            HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" 
            Checked = "RadioButton_Checked"/>
				
      </StackPanel> 
		
      <StackPanel x:Name = "StatusBarControls" Orientation = "Vertical" 
         Margin = "75,350,0,0" Visibility = "Visible">
			
         <CheckBox x:Name = "StatusBarBackgroundCheckBox" 
            Content = "Set StatusBar Background"
            Checked = "StatusBarBackgroundCheckBox_Checked" 
            Unchecked = "StatusBarBackgroundCheckBox_Unchecked"/>
				
         <CheckBox x:Name = "StatusBarHiddenCheckBox" 
            Content = "Set StatusBar Hidden" Checked = "StatusBarHiddenCheckBox_Checked"
            Unchecked = "StatusBarHiddenCheckBox_Unchecked"/> 
				
      </StackPanel> 
		
   </Grid> 
	
</Page>	

以下是不同事件的 C# 實現。

using Windows.UI; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls;  

// The Blank Page item template is documented at
   http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409  

namespace UWPAdoptiveCode { 
   /// <summary> 
      /// An empty page that can be used on its own or navigated to within a Frame. 
   /// </summary> 
	
   public sealed partial class MainPage : Page { 
     
      private Color? DefaultTitleBarButtonsBGColor; 
      private Color? DefaultTitleBarBGColor;
		
      public MainPage() {
         this.InitializeComponent();
			
         //Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().
            VisibleBoundsCh anged += MainPage_VisibleBoundsChanged;
				
         var viewTitleBar = Windows.UI.ViewManagement.ApplicationView.
            GetForCurrentView().TitleBar; 
				
         DefaultTitleBarBGColor = viewTitleBar.BackgroundColor; 
         DefaultTitleBarButtonsBGColor = viewTitleBar.ButtonBackgroundColor; 
      } 
		
      private void RadioButton_Checked(object sender, RoutedEventArgs e) {
        
         // Bottom AppBar shows on Desktop and Mobile 
         if (ShowAppBarRadioButton != null) {
			  
            if (ShowAppBarRadioButton.IsChecked.HasValue &&
               (ShowAppBarRadioButton.IsChecked.Value == true)) {
                 commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; 
                 commandBar.Opacity = 1; 
            } else {
               commandBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed; 
            } 
         } 
			
         if (ShowOpaqueAppBarRadioButton != null) {
             
            if (ShowOpaqueAppBarRadioButton.IsChecked.HasValue &&
               (ShowOpaqueAppBarRadioButton.IsChecked.Value == true)){ 
                  commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; 
                  commandBar.Background.Opacity = 0; 
            } else{ 
               commandBar.Background.Opacity = 1; 
            } 
         } 
			
      } 
		
      private void StatusBarHiddenCheckBox_Checked(object sender, RoutedEventArgs e){
        
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ 
               var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync(); 
         } 
      } 
		
      private void StatusBarHiddenCheckBox_Unchecked(object sender, RoutedEventArgs e){
	  
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){
               var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().ShowAsync(); 
         } 
      }  
		
      private void StatusBarBackgroundCheckBox_Checked(object sender, RoutedEventArgs e){
       
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ 
				
               Windows.UI.ViewManagement.StatusBar.GetForCurrentView().
                  BackgroundColor = Windows.UI.Colors.Blue; 
					
               Windows.UI.ViewManagement.StatusBar.GetForCurrentView().
                   BackgroundOpacity = 1; 
         } 
      }  
		
      private void StatusBarBackgroundCheckBox_Unchecked(object sender, RoutedEventArgs e){
         
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){
               Windows.UI.ViewManagement.StatusBar.GetForCurrentView().
                  BackgroundOpacity = 0; 
         } 
      } 
		
   } 
	
   public class DeviceFamilyTrigger : StateTriggerBase{
    
      //private variables 
      private string _deviceFamily;
	  
      //Public property 
      public string DeviceFamily {
         
         get {
            return _deviceFamily; 
         } 
         set{
            _deviceFamily = value; 
            var qualifiers = Windows.ApplicationModel.Resources.Core.ResourceContext.
               GetForCurrentView().Qua lifierValues; 
					
            if (qualifiers.ContainsKey("DeviceFamily")) 
               SetActive(qualifiers["DeviceFamily"] == _deviceFamily); 
            else 
               SetActive(false); 
         } 
      } 
   } 
} 

當以上程式碼在手機上編譯並執行時,您將看到以下視窗。

Adaptive Code Execute

您可以使用複選框更改狀態列的背景顏色,如影像所示。

Adaptive Code Execute Status

您還可以隱藏狀態列。

Adaptive Code Execute Status Bar

現在,當您在桌面裝置上執行相同的應用程式時,您將看到以下視窗,其中狀態列和特定於狀態列的複選框不可見。

Adaptive Code Execute Status Bar checkbox
廣告

© . All rights reserved.