Учебники

Разработка для Windows 10 — Адаптивный код

В этой главе мы продемонстрируем адаптацию вашего приложения к различным устройствам, поддерживаемым Windows 10. Мы уже узнали о принятии вашего пользовательского интерфейса и всех приемах, методах и элементах управления, используемых в приложениях UWP.

Теперь мы узнаем о принятии вашего кода, потому что

  • Коды приложений не одинаковы для всех устройств.

  • Используемые API, особенно для Xbox, не будут доступны для мобильных устройств. То же самое относится и к HoloLens и т. Д.

Коды приложений не одинаковы для всех устройств.

Используемые API, особенно для Xbox, не будут доступны для мобильных устройств. То же самое относится и к HoloLens и т. Д.

Устройства Windows

Адаптивный код может условно освещать ваше приложение и выполнять код только при запуске на определенном семействе устройств и / или на определенной версии API-интерфейсов платформы / расширения.

Написание кода

В Windows 10 вы можете реализовать приложения UWP в Visual Studio, используя C ++, C #, Visual Basic или JavaScript.

  • С C # и Visual Basic вы можете использовать XAML для проектирования пользовательского интерфейса.

  • С C ++ вы можете использовать DirectX вместо XAML.

  • Для JavaScript вы можете использовать HTML для уровня презентации, который является кросс-платформенным веб-стандартом.

С C # и Visual Basic вы можете использовать XAML для проектирования пользовательского интерфейса.

С C ++ вы можете использовать DirectX вместо XAML.

Для JavaScript вы можете использовать HTML для уровня презентации, который является кросс-платформенным веб-стандартом.

Windows Core API работают одинаково для всех устройств, которые содержат большую часть функциональности, необходимой для вашего кода и пользовательского интерфейса. Однако для кода и пользовательского интерфейса, предназначенных для определенных семейств устройств, необходимо использовать адаптивный код и адаптивный пользовательский интерфейс.

Вызов API, который НЕ реализован целевым семейством устройств —

Пользовательский интерфейс легко адаптируется к различным экранам, но разные семейства устройств не только имеют разные размеры экрана, но и намного больше.

  • Например, на мобильных телефонах есть некоторые аппаратные кнопки, такие как «Назад» и «Камера», которые могут быть недоступны на других устройствах, таких как ПК.

  • По умолчанию основные API-интерфейсы содержат большую часть функциональности, которая работает для всех устройств, но специальные функциональные возможности устройства можно использовать, ссылаясь на SDK-расширения в ваших приложениях UWP, как внешние сборки.

Например, на мобильных телефонах есть некоторые аппаратные кнопки, такие как «Назад» и «Камера», которые могут быть недоступны на других устройствах, таких как ПК.

По умолчанию основные API-интерфейсы содержат большую часть функциональности, которая работает для всех устройств, но специальные функциональные возможности устройства можно использовать, ссылаясь на SDK-расширения в ваших приложениях UWP, как внешние сборки.

Чтобы добавить какой-либо конкретный SDK расширения, необходимый в вашем приложении, выполните следующие действия:

  • Щелкните правой кнопкой мыши на References .

  • Выберите «Добавить ссылки ..» . Следующий диалог откроется.

Щелкните правой кнопкой мыши на References .

Выберите «Добавить ссылки ..» . Следующий диалог откроется.

Менеджер добавления ссылок

  • Добавить расширение так же просто, как добавить ссылку на проект.

  • Теперь вы можете добавить любое расширение SDK из списка, который содержит расширение Desktop, расширение IoT, расширение Mobile и т. Д.

Добавить расширение так же просто, как добавить ссылку на проект.

Теперь вы можете добавить любое расширение SDK из списка, который содержит расширение Desktop, расширение IoT, расширение Mobile и т. Д.

Настольные и мобильные расширения — это два наиболее распространенных SDK расширения платформы. Например, расширение Mobile позволяет 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; 
} 

Код кнопки телефона и камеры будет выполняться только в том случае, если на устройстве включен Mobile Extension SDK. Аналогично, вы также можете проверить наличие какого-либо конкретного события, метода или свойства в текущей версии API, используя IsEventPresent , IsMethodPresent , IsPropertyPresent вместо IsTypePresent, как показано ниже.

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

Win32 API в UWP

Приложение универсальной платформы вдов (UWP) или компонент среды выполнения Windows, написанные на C ++ / CX, могут получать доступ к API-интерфейсам Win32, которые также являются частью UWP. Все семейства устройств Windows 10 могут реализовывать Win32 API, связывая ваше приложение с Windowsapp.lib .

Windowsapp.lib является «зонтичной» библиотекой, которая обеспечивает экспорт для API UWP. Ссылка на Windowsapp.lib добавит к вашему приложению зависимости от dll , которые присутствуют на всех семействах устройств Windows 10.

Давайте рассмотрим простой пример, в котором приложение предназначено как для настольного компьютера, так и для телефона. Поэтому, когда приложение запускается на рабочем столе, оно не отображает строку состояния, но когда то же приложение запускается на телефоне, оно отображает строку состояния.

Ниже приведен код 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); 
         } 
      } 
   } 
} 

Когда приведенный выше код скомпилирован и выполнен на мобильном телефоне, вы увидите следующее окно.

Адаптивный код Выполнить

Вы можете изменить цвет фона строки состояния с помощью флажка, как показано на рисунке.

Статус выполнения адаптивного кода

Вы также можете скрыть строку состояния.

Строка состояния выполнения адаптивного кода

Теперь, когда вы запустите одно и то же приложение на настольном устройстве, вы увидите следующее окно, в котором строка состояния и флажки, относящиеся к строке состояния, не видны.