Сводка по главе 2. Анатомия приложения

Download Sample Скачайте пример

Примечание.

Эта книга была опубликована весной 2016 года и с тех пор не обновлялась. Многое в этой книге остается ценным, но некоторые материалы устарели, а некоторые разделы перестали быть полностью верными или полными.

В приложении Xamarin.Forms любые объекты, занимающие место на экране, называются визуальными элементами и инкапсулируются в класс VisualElement. Визуальные элементы можно разделить на три категории, соответствующие следующим классам:

Производные Page занимают весь или почти весь экран. Дочерний объект страницы обычно наследуется от Layout и служит для организации дочерних визуальных элементов. Дочерние объекты Layout также могут быть классами Layoutили производными от View, и тогда они называются элементами. Сюда относятся текстовые поля, точечные рисунки, ползунки, кнопки, списки и т. д.

В этой главе показано, как создать приложение на основе Label, — производного элемента от View для отображения текста.

Начнем с приветствия

После установки платформы Xamarin можно создать новое решение Xamarin.Forms с помощью Visual Studio или Visual Studio для Mac. Решение Hello использует переносимую библиотеку классов для общего кода.

Примечание.

Переносимые библиотеки классов заменены библиотеками .NET Standard. Все примеры кода в этой книге преобразованы для использования библиотек .NET Standard.

В этом примере демонстрируется решение Xamarin.Forms, созданное в Visual Studio, без дополнительных изменений. Это решение состоит из четырех проектов:

  • Hello — переносимая библиотека классов (PCL), совместно используемая другими проектами;
  • Hello.Droid — проект приложения для Android;
  • Hello.iOS — проект приложения для iOS;
  • Hello.UWP — проект приложения для универсальной платформы Windows (Windows 10 и Windows 10 Mobile).

Примечание.

Xamarin.Forms теперь не поддерживает Windows 8.1, Windows Phone 8.1 и Windows 10 Mobile, при этом приложения Xamarin.Forms выполняются в Windows 10 для настольных компьютеров.

Вы можете назначить любой из этих проектов приложения запускаемым проектом, а затем скомпилировать и запустить программу на реальном устройстве или в симуляторе.

Во многих программах Xamarin.Forms вам не нужно будет вносить изменения в проекты приложений. Чаще всего это лишь маленькие заглушки, которые нужны только для запуска программы. Основное внимание уделяется библиотеке, которая используется совместно всеми приложениями.

Внутреннее строение файлов

Визуальные элементы, отображаемые программой Hello, определены в конструкторе класса App. App является производным от класса ApplicationXamarin.Forms.

Примечание.

Шаблоны решений Visual Studio для Xamarin.Forms создают страницу на основе файла XAML. Структура XAML не рассматривается в этой книге вплоть до главы 7.

Раздел References в проекте PCL Hello включает следующие сборки Xamarin.Forms:

  • Xamarin.Forms.Core
  • Xamarin.Forms.Xaml
  • Xamarin.Forms.Platform

Разделы References всех пяти проектов приложений включают дополнительные сборки, которые нужны для конкретных платформ:

  • Xamarin.Forms.Platform.Android
  • Xamarin.Forms.Platform.iOS
  • Xamarin.Forms.Platform.UWP
  • Xamarin.Forms.Platform.WinRT
  • Xamarin.Forms.Platform.WinRT.Tablet
  • Xamarin.Forms.Platform.WinRT.Phone

Примечание.

Разделы References этих проектов теперь не содержат списка сборок. Вместо этого файл проекта содержит теги PackageReference, которые указывают нужный пакет NuGet для Xamarin.Forms. В разделе Ссылки в Visual Studio указан пакет Xamarin.Forms, а не сборки Xamarin.Forms.

Каждый проект приложения содержит вызов статического метода Forms.Init из пространства имен Xamarin.Forms. Он инициализирует библиотеку Xamarin.Forms. Для каждой платформы определена собственная версия Forms.Init. Вызовы этого метода присутствуют в следующих классах:

Кроме того, каждая платформа создает экземпляр расположения класса App в общей библиотеке. Это выполняется в вызове LoadApplication в следующих классах:

Во всем остальном эти проекты приложений являются обычными программами, которые сами не выполняют никаких действий.

PCL или SAP?

Вы можете создать решение Xamarin.Forms, разместив общий код в переносимой библиотеке классов (PCL) или проекте общих ресурсов (SAP). Чтобы создать решение на основе SAP, выберите в Visual Studio вариант "Общий". Решение HelloSap демонстрирует шаблон SAP без дополнительных изменений.

Примечание.

Переносимые библиотеки классов здесь заменены библиотеками .NET Standard. Все примеры кода в этой книге преобразованы для использования библиотек .NET Standard. В остальном библиотеки PCL и .NET Standard очень похожи.

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

Большинство разработчиков Xamarin.Forms предпочитают подход с использованием библиотек. В этой книге большинство решений используют библиотеки. В проектах, в которых используется SAP, к имени добавлен суффикс Sap.

В рамках подхода с использованием SAP код в общем проекте может выполнять разные коды на разных платформах, используя директивы препроцессора C# (#if, #elif и #endif) со следующими идентификаторами:

  • iOS: __IOS__
  • Android: __ANDROID__
  • UWP: WINDOWS_UWP

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

Метки для текста

Решение Greetings демонстрирует, как добавить новый файл кода C# в проект Greetings. Этот файл определяет класс с именем GreetingsPage, производный от ContentPage. В этой книге большинство проектов содержат один производный класс ContentPage, имя которого включает имя проекта и суффикс Page.

Конструктор GreetingsPage создает экземпляр представления Label, которое создано в Xamarin.Forms для отображения текста. Свойство Text содержит текст, отображаемый элементом Label. Эта программа присваивает значение Label свойству Content элемента ContentPage. Затем конструктор класса App создает экземпляр GreetingsPage и сохраняет его в свойстве MainPage.

Соответствующий текст появляется в левом верхнем углу страницы. В iOS этот текст перекрывает строку состояния страницы. Эту проблему можно решить несколькими способами.

Решение 1. Добавление отбивки к странице

Присвойте значение свойству Padding страницы. Padding имеет тип Thickness. Это структура с четырьмя свойствами:

Padding определяет область внутри страницы, где отсутствует содержимое. Это позволяет Label не перекрывать строку состояния iOS.

Решение 2. Добавление отбивки только для iOS (применимо только для SAP)

Задайте свойство Padding только для iOS, используя директиву препроцессора C# в решении на основе SAP. Этот метод представлен в решении GreetingsSap.

Решение 3. Добавление отбивки только для iOS (применимо для PCL или SAP)

В той версии Xamarin.Forms, которая используется в этой книге, в PCL или SAP можно использовать характерное для iOS свойство Padding, выбираемое с помощью статического метода Device.OnPlatform или Device.OnPlatform<T>. Сейчас эти методы считаются нерекомендуемыми.

Методы Device.OnPlatform используются для выполнения кода, зависящего от платформы, или для выбора значений, зависящих от платформы. На внутреннем уровне они используют статическое свойство только для чтения Device.OS, которое возвращает элемент перечисления TargetPlatform:

Методы Device.OnPlatform, свойство Device.OS и перечисление TargetPlatform сейчас считаются нерекомендуемыми. Используйте вместо них свойство Device.RuntimePlatform и сравнивайте возвращаемое значение string со следующими статическими полями:

  • iOS — строковое значение iOS;
  • Android — строковое значение Android;
  • UWP — строковое значение UWP, которое обозначает универсальную платформу Windows.

Также есть связанное свойство только для чтения Device.Idiom. Оно возвращает элемент TargetIdiom, который содержит следующие элементы:

В iOS и Android срез между Tablet и Phone обозначает портретную ориентацию с шириной 600 единиц. В Windows Desktop обозначает приложение UWP под управлением Windows 10, а Phone — приложение UWP под управлением приложения Windows 10.

Решение 3а. Добавление полей для метки

Свойство Margin появилось после составления этой книги, но оно также имеет тип Thickness. Его можно задать для Label, чтобы определить область вокруг этого представления, которая учитывается при вычислении макета представления.

Свойство Padding доступно только для производных от Layout и Page. Свойство Margin доступно для всех производных от View.

Решение 4. Центрирование метки по странице

Вы можете разместить Label по центру Page (или в одно из других восьми мест), задав для свойств HorizontalOptions и VerticalOptions объекта Label значение с типом LayoutOptions. Структура LayoutOptions определяет два свойства.

  • Свойство Alignment с типом LayoutAlignment является перечислением с четырьмя членами: Start для левого или верхнего края в зависимости от ориентации, Center, End для правого или нижнего края в зависимости от ориентации и Fill.

  • Свойство Expands с типом bool.

Обычно эти свойства не используются напрямую. Каждое возможное сочетание этих двух свойств представлено восемью статическими свойствами только для чтения с типом LayoutOptions:

HorizontalOptions и VerticalOptions являются наиболее важными свойствами в Xamarin.Forms макете и подробно рассматриваются в главе 4. Прокрутка стека.

Ниже приведен результат отображения, в котором свойства HorizontalOptions и VerticalOptions объекта Label имеют значение LayoutOptions.Center:

Triple screenshot of greetings program

Решение 5. Центрирование текста по метке

Можно также центрировать текст (или поместить его в восемь других расположений на странице), присвоив свойствам HorizontalTextAlignment и VerticalTextAlignment объекта Label значение одного из членов перечисления TextAlignment:

  • Start обозначает левый или верхний край (в зависимости от ориентации);
  • Center
  • End обозначает правый или нижний край (в зависимости от ориентации).

Эти два свойства определяются только для Label, тогда как свойства HorizontalAlignment и VerticalAlignment определяются для View и наследуются всеми производными View. В визуальном представлении они очень похожи, но в следующей главе мы продемонстрируем их существенные отличия.