Статьи

Компоненты кремнезема для пользовательских интерфейсов в Sailfish OS

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

Он имеет JSON-подобный синтаксис с поддержкой выражений Javascript и динамических привязок свойств. Одна из его ключевых особенностей заключается в том, что он хорошо читается и позволяет повторно использовать и настраивать компоненты в пользовательском интерфейсе.

С QML создание высокопроизводительных, гибких и привлекательных приложений становится простым, а модуль QtQuick предоставляет основные компоненты для запуска.

Sailfish SDK включает в себя Sailfish Silica, модуль расширения QML, предоставляющий дополнительные типы, предназначенные для использования приложениями Sailfish.

При написании приложений Sailfish с QML вам необходимо использовать модули Sailfish Silica и QtQuick. Вы должны использовать Silica всякий раз, когда это возможно, поскольку эти компоненты имеют внешний вид Sailfish, ведут себя согласованно со стандартными приложениями Sailfish и позволяют приложениям использовать уникальные функции Sailfish, такие как меню шкивов и обложки приложений.

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

Основные компоненты

QTQuick предоставляет базовые типы объектов, которые понадобятся приложению, такие как Image , Rectangle , Circle , Item и ListView . Полный список можно найти здесь .

Любой из них может использоваться в приложениях Sailfish, но вы должны использовать правильные компоненты Silica, когда они доступны (SilicaListView против ListView, SilicaGridView против GridView и т. Д.), Поскольку они имеют внешний вид Sailfish.

Чтобы использовать эти компоненты, просто добавьте следующее в свой файл QML:

 import QtQuick 2.0 

И в файле QML добавьте:

 import Sailfish.Silica 1.0 

начать использовать компоненты кремнезема.

тема

Теперь давайте обсудим компоненты кремнезема. Объект Theme предоставляет общую информацию о стиле, такую ​​как цвета, шрифты и поля. Цвета будут соответствовать выбранной пользователем обстановке.

Давайте начнем с примера:

 Text { color: Theme.primaryColor font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeMedium } 

Элемент Text — это форматированное текстовое представление только для чтения. Здесь я определил три наиболее распространенных свойства текста, используя свойство относительной темы. Объект Theme определяет набор свойств для размеров, цветов и шрифтов:

В пользовательском интерфейсе Sailfish используются два стандартных шрифта:

  • Theme.fontFamily — шрифт по умолчанию, используемый для метки, кнопки и т. Д.
  • Theme.fontFamilyHeading — используется для отображения текста заголовка. Заголовки, заголовки страниц и т. Д.

Размер пикселя шрифта определяется этими свойствами:

  • Theme.fontSizeExtraSmall
  • Theme.fontSizeSmall
  • Theme.fontSizeMedium
  • Theme.fontSizeLarge
  • Theme.fontSizeExtraLarge

И значения цвета:

  • Theme.primaryColor — используется для ярлыков
  • Theme.secondaryColor — используется для менее заметных частей пользовательского интерфейса
  • Theme.highlightColor — используется для активных и выделенных областей пользовательского интерфейса
  • Theme.secondaryHighlightColor — менее заметный цвет подсветки

В модуле Silica доступен компонент Label, и его следует использовать предпочтительнее элемента Text, поскольку он использует свойства, указанные выше.

Наконец, объект Theme предоставляет все стандартные размеры элемента и значения заполнения:

  • itemSizeSmall — небольшой размер элемента, например, используемый в элементах списка в одну строку
  • itemSizeMedium — средний размер элемента, например, используемый в элементах списка из двух строк
  • itemSizeLarge — большой размер элемента, используемый в сложных элементах списка, используемый в элементах с некоторым содержимым для предварительного просмотра
  • itemSizeExtraLarge — очень большой размер элемента, четверть ширины портрета, используемый в сетках заголовков списка
  • paddingSmall — небольшой отступ, обычно используемый между метками близко друг к другу
  • paddingMedium — средний отступ, общее поле в компонентах пользовательского интерфейса
  • paddingLarge — большой отступ, обычно используемый в качестве поля страницы вблизи границ экрана

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

Page и PageStack

Page определяет отдельный экран контента, к которому пользователь может перемещаться из приложения. Обычно он соответствует полной ширине и высоте экрана для текущей ориентации. Его размер можно изменить из-за изменения ориентации или отображения панели ввода.

Чтобы обеспечить SilicaFlickable содержимого, если страница слишком мала, поместите все в SilicaFlickable .

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

Пример:

Пример страницы

 import QtQuick 2.0 import Sailfish.Silica 1.0 Page { SilicaFlickable { contentHeight: column.height anchors.fill: parent VerticalScrollDecorator {} Column { spacing: Theme.paddingLarge id: column width: parent.width PageHeader { title: "Silica components" id: header } Label { text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus fringilla velit eu augue viverra hendrerit. Praesent commodo ornare enim eget laoreet. Quisque dignissim, sem non molestie sodales, orci nulla ornare lectus, ac consectetur tellus metus in tellus. Fusce in vulputate enim. Vestibulum a hendrerit ligula." font.pixelSize: Theme.fontSizeSmall wrapMode: Text.Wrap anchors { left: parent.left right: parent.right margins: Theme.paddingLarge } } } } } 

Выше я определил Page , содержащую только одного дочернего SilicaFlickable , SilicaFlickable чтобы гарантировать, что если содержимое будет слишком длинным, его можно будет прокручивать. Я добавил VerticalScrollDecorator для визуальной обратной связи с пользователем при прокрутке.

После этого компоненты Column и QtQuick используются для вертикального позиционирования ряда элементов без использования якорей. Я использовал объект Theme чтобы установить свойство spacing.

Я использовал тип PageHeader для отображения заголовка страницы и, наконец, создал Label с некоторым текстом и свойством для его отображения по PageHeader желанию.

Страницы обрабатываются с помощью стековой модели навигации, предоставляемой типом PageStack . Наше ApplicationWindow (компонент верхнего уровня приложения Sailfish) имеет свойство pageStack которое содержит его экземпляр, всегда отображая самую верхнюю страницу в своем стеке страниц.

Страница может быть помещена (метод push() ) в стек, чтобы поместить ее на вершину стека, или извлечена pop() метод pop() ), чтобы удалить ее.

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

Индикатор страницы

На изображении выше вы можете видеть, что индикаторы в верхнем левом (или верхнем правом) полях стека страниц указывают, можно ли перелистать страницу назад или вперед. Жесты навигации могут вызываться прагматично с помощью функций navigateBack() и navigateForward() .

Например, если я добавлю этот код как дочерний элемент объекта Column :

 Button { text: "next page" onClicked: pageStack.push("MyPage.qml") } Button { text: "previous page" onClicked: pageStack.pop() } 

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

Покрытие

Активные чехлы являются одним из отличительных элементов Sailfish. Это визуальное представление приложения, работающего в фоновом режиме, и оно будет видно на главном экране.

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

ApplicationWindow содержит экземпляр Cover, который может быть создан с использованием элемента верхнего уровня, типа CoverBackground :

Активное покрытие

 import QtQuick 2.0 import Sailfish.Silica 1.0 CoverBackground { Image { id:background fillMode: Image.PreserveAspectCrop source: "landscape.png" } Label { anchors.centerIn: parent id: label width: parent.width horizontalAlignment: Text.AlignHCenter text: "Hello cover" } CoverActionList { id: coverAction CoverAction { iconSource: "image://theme/icon-cover-new" onTriggered: addItem() } } function addItem() { console.log("Adding item") } } 

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

Я добавил центрированную метку и CoverActionList с одним CoverAction .

CoverAction указывает действие, которое необходимо выполнить при активации жеста обложки. Это определяется значком и функцией, которая должна быть запущена в нужное время. Парусник обрабатывает только два CoverAction s для покрытия. Вы можете увидеть, как javascipt-подобные функции и синтаксис могут использоваться в QML для объявления функций и использования их в качестве обратного вызова для событий.

RemorsePopup и RemorseItem

Еще один интересный элемент в наборе инструментов Sailfish UI — RemorsePopup .

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

Раскаяние Popup

Пользователь может нажать на всплывающее окно до истечения времени ожидания и отменить разрушительное действие.

RemorsePopup легко. Если у меня есть кнопка «Удалить»:

 Button { text: "Delete Item" onClicked: deleteItem() } 

Оставляя метод deleteItem , я могу просто изменить код следующим образом:

 Button { id: button text: "Delete Item" onClicked: remorse.execute("Deleting", deleteItem ) RemorsePopup { id: remorse } } 

Когда пользователь нажимает кнопку, RemorsePopup будет отображаться с указанным текстом.

По истечении времени deleteItem будет deleteItem обратный вызов deleteItem .

Тип RemorseItem работает таким же образом, но его можно присоединить к объекту (например, элементу списка), где он станет родным для своего целевого родителя.

Шкив меню

В Sailfish меню обычно представлены в виде меню шкива. Он расположен над / под содержимым вида и доступен путем перетаскивания вида вниз / вверх. Пункты меню активируются либо:

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

Для работы необходимо добавить меню SilicaFlickable в SilicaFlickable , SilicaListView , SilicaGridView или SilicaWebView .

PullDownMenu используется для создания меню шкива, и оно будет заполнено объявлением объектов MenuItem как его дочерних PullDownMenu .

Шкив меню

 import QtQuick 2.0 import Sailfish.Silica 1.0 Page { SilicaListView { PullDownMenu { MenuItem { text: "Option 1" onClicked: console.log("Clicked option 1") } MenuItem { text: "Option 2" onClicked: console.log("Clicked option 2") } } header: PageHeader { title: "Header" } delegate: MyListItem {} model: MyModel {} } } 

ViewPlaceholder

Другим удобным компонентом является ViewPlaceholder . Он предоставляет заполнитель текста, который будет отображаться в пустых представлениях, когда контент недоступен.

Таким образом, пользователь будет знать, что приложение готово, но нечего показывать.

Если у представления есть PullDownMenu , при нажатии на ViewPlaceholder отобразится меню, чтобы указать пользователю, что опции могут быть доступны.

 Page { SilicaListView { id: view anchors.fill: parent model: ListModel { } ViewPlaceholder { enabled: view.count == 0 text: "Nothing to show now" } delegate: BackgroundItem { width: view.width Label { text: "Item " + index } } } } 

В этом примере я добавил ViewPlaceholder в SilicaListView и SilicaListView его свойство enabled со свойством count самого списка.

Как только мы добавим что-то в модель списка, наш ViewPlaceholder исчезнет.

диалог

Dialog — это универсальный контейнер для отображения диалога, который принимает пользовательский ввод. Он будет отображаться как модальное диалоговое окно, добавленное к вершине PageStack . Пользователь может принять диалоговое окно (подтверждение изменений или ввод и продолжение), нажав страницу справа налево или нажав кнопку «Принять». И наоборот, диалоговое окно отклоняется путем нажатия на страницу слева направо или нажатия кнопки «Отмена».

Простой диалог создается следующим образом:

Пример диалога

 import QtQuick 2.0 import Sailfish.Silica 1.0 Dialog { property string name Column { width: parent.width DialogHeader { } TextField { id: nameField width: 480 placeholderText: "What's your name?" } } onDone: { if (result == DialogResult.Accepted) { name = nameField.text } } } 

Событие onDone будет onDone , когда пользователь примет или отклонит диалог. DialogResult.Accepted содержит намерение пользователя.

DialogHeader должен использоваться для отображения индикаторов страницы в верхней части диалоговой страницы.

Диалог может быть отображен, толкая его к pageStack как обычная страница.

 Column { Label { id: displayedName } Button { text: "Ask me" onClicked: { var dialog = pageStack.push("NameInputDialog.qml", {"name": displayedName.text}) dialog.accepted.connect(function() { displayedName.text = "My name: " + dialog.name }) } } } 

Выше я подключил сигнал «принят» в диалоге к функции javascript, которая обновляла метку, используя свойство name диалога (устанавливается, когда диалог принимается).

Если диалоговое окно отклонено, onRejected обработчик сигнала onRejected и в результате устанавливается значение DialogResult.Rejected .

Вывод

Это краткое введение в наиболее популярные компоненты Silica, которые важно понимать и правильно использовать для создания нативного приложения с внешним видом Sailfish. Я буду освещать больше компонентов более подробно в будущих статьях. А пока наслаждайтесь Sailfish, и я хотел бы узнать ваше мнение.